Unity3D协同程序(Coroutine)

一。什么是协同程序

协同程序,即在主程序运行时同时开启另一段逻辑处理,来协同当前程序的执行。换句话说,开启协同程序就是开启一个线程。

二。协同程序的开启与终止

在Unity3D中,使用MonoBehaviour.StartCoroutine方法即可开启一个协同程序,也就是说该方法必须在MonoBehaviour或继承于MonoBehaviour的类中调用。

在Unity3D中,使用StartCoroutine(string  methodName)和StartCoroutine(IEnumerator  routine)都可以开启一个线程。区别在于使用字符串作为参数可以开启线程并在线程结束前终止线程,相反使用IEnumerator 作为参数只能等待线程的结束而不能随时终止(除非使用StopAllCoroutines()方法);另外使用字符串作为参数时,开启线程时最多只能传递 一个参数,并且性能消耗会更大一点,而使用IEnumerator 作为参数则没有这个限制。

在Unity3D中,使用StopCoroutine(string  methodName)来终止一个协同程序,使用StopAllCoroutines()来终止所有可以终止的协同程序,但这两个方法都只能终止该MonoBehaviour中的协同程序。

还有一种方法可以终止协同程序,即将协同程序所在gameobject的active属性设置为false,当再次设置active为ture时,协同程 序并不会再开启;如是将协同程序所在脚本的enabled设置为false则不会生效。这是因为协同程序被开启后作为一个线程在运行,而MonoBehaviour也是一个线程,他们成为互不干扰的模块,除非代码中用调用,他们共同作用于同一个对象,只有当对象不可见才能同时终止这两个线 程。然而,为了管理我们额外开启的线程,Unity3D将协同程序的调用放在了MonoBehaviour中,这样我们在编程时就可以方便的调用指定脚本 中的协同程序,而不是无法去管理,特别是对于只根据方法名来判断线程的方式在多人开发中很容易出错,这样的设计保证了对象、脚本的条理化管理,并防止了重 名。

三。协同程序的输入、输出类型

协同程序的返回类型为Coroutine类型。在Unity3D中,Coroutine类继承于YieldInstruction,所以,协同程序的返回类型只能为null、等待的帧数(frame)以及等待的时间。

协同程序的参数不能指定ref、out参数。但是,我们在使用WWW类时会经常使用到协同程序,由于在协同程序中不能传递参数地址(引用),也不能输出对 象,这使得每下载一个WWW对象都得重写一个协同程序,解决这个问题的方法是建立一个基于WWW的类,并实现一个下载方法。如下:

usingUnityEngine;
usingSystem.Collections;

publicclassWWWObject:MonoBehaviour
{
public WWW www;

publicWWWObject(string url)
{
  if(GameVar.wwwCache)
   www =WWW.LoadFromCacheOrDownload(url,GameVar.version);
  else
   www =new WWW(url);
}

publicIEnumeratorLoad()
{
  Debug.Log("Start loading : "+www.url);
  while(!www.isDone)
  {
   if(GameVar.gameState ==GameState.Jumping||GameVar.gameState ==GameState.JumpingAsync)
    LoadScene.progress =www.progress;
   
   yieldreturn1;
  }

if(www.error!=null)
   Debug.LogError("Loading error : "+www.url+"\n"+www.error);
  else
   Debug.Log("End loading : "+www.url);
}

publicIEnumeratorLoadWithTip(string resourcesName)
{
  Debug.Log("Start loading : "+www.url);
  LoadScene.tipStr =  "Downloading  resources <"+ resourcesName +"> . . .";
  while(!www.isDone)
  {
   if(GameVar.gameState ==GameState.Jumping||GameVar.gameState ==GameState.JumpingAsync)
    LoadScene.progress =www.progress;
   
   yieldreturn1;
  }

if(www.error!=null)
   Debug.LogError("Loading error : "+www.url+"\n"+www.error);
  else
   Debug.Log("End loading : "+www.url);
}
}

调用:

usingUnityEngine;
usingSystem.Collections;
usingSystem.Collections.Generic;

publicclassLoadResources:MonoBehaviour
{
staticstring url ="http://61.149.211.88/Package/test.unity3d";
publicstatic WWW www =null;

IEnumeratorStart()
{
  if(!GameVar.resourcesLoaded)
  {  
   GameVar.gameState =GameState.Jumping;
   
   WWWObject obj =newWWWObject(url);
   www = obj.www;
   yieldreturnStartCoroutine(obj.LoadWithTip("Textures"));
   
   GameVar.resourcesLoaded =true;
   GameVar.gameState =GameState.Run;
  }
}
}

时间: 2024-10-31 09:24:06

Unity3D协同程序(Coroutine)的相关文章

Lua之协同程序(coroutine)

什么是协同(coroutine)? Lua 协同程序(coroutine)与线程比较类似:拥有独立的堆栈,独立的局部变量,独立的指令指针,同时又与其它协同程序共享全局变量和其它大部分东西. 协同是非常强大的功能,但是用起来也很复杂. 线程和协同程序区别 线程与协同程序的主要区别在于,一个具有多个线程的程序可以同时运行几个线程,而协同程序却需要彼此协作的运行. 在任一指定时刻只有一个协同程序在运行,并且这个正在运行的协同程序只有在明确的被要求挂起的时候才会被挂起. 协同程序有点类似同步的多线程,在

雷林鹏分享:Lua 协同程序(coroutine)

什么是协同(coroutine)? Lua 协同程序(coroutine)与线程比较类似:拥有独立的堆栈,独立的局部变量,独立的指令指针,同时又与其它协同程序共享全局变量和其它大部分东西. 协同是非常强大的功能,但是用起来也很复杂. 线程和协同程序区别 线程与协同程序的主要区别在于,一个具有多个线程的程序可以同时运行几个线程,而协同程序却需要彼此协作的运行. 在任一指定时刻只有一个协同程序在运行,并且这个正在运行的协同程序只有在明确的被要求挂起的时候才会被挂起. 协同程序有点类似同步的多线程,在

转载 Unity3D协同程序(Coroutine)

摘要下: 1. coroutine, 中文翻译"协程".这个概念可能有点冷门,不过百度之,说是一种很古老的编程模型了,以前的操作系统里进程调度里用到过,现在操作系统的进程调度都是根据 时间片和优先级来进行轮换,以前是要程序自己来释放cpu的控制权,一直不释放一直也就占用着cpu,这种要求程序自己来进行调度的编程模型应该就叫"协 程"了. 协程和线程差不多,线程的调度是由操作系统完成的,协程把这项任务交给了程序员自己实现,当然也就可以提高灵活性,另外协程的开销比线程要

Lua中的协同程序 coroutine

Lua中的协程和多线程很相似,每一个协程有自己的堆栈,自己的局部变量,可以通过yield-resume实现在协程间的切换.不同之处是:Lua协程是非抢占式的多线程,必须手动在不同的协程间切换,且同一时刻只能有一个协程在运行.并且Lua中的协程无法在外部将其停止,而且有可能导致程序阻塞. 协同程序(Coroutine): 三个状态:suspended(挂起,协同刚创建完成时或者yield之后).running(运行).dead(函数走完后的状态,这时候不能再重新resume). coroutine

Lua中的协同程序 coroutine(转)

Lua中的协程和多线程很相似,每一个协程有自己的堆栈,自己的局部变量,可以通过yield-resume实现在协程间的切换.不同之处是:Lua协程是非抢占式的多线程,必须手动在不同的协程间切换,且同一时刻只能有一个协程在运行.并且Lua中的协程无法在外部将其停止,而且有可能导致程序阻塞. 协同程序(Coroutine): 三个状态:suspended(挂起,协同刚创建完成时或者yield之后).running(运行).dead(函数走完后的状态,这时候不能再重新resume). coroutine

Lua 学习之基础篇九&lt;Lua 协同程序(Coroutine)&gt;

引言 讲到协程,首先来介绍一下线程和协程的区别 lua协程和多线程 相同之处:拥有自己独立的桟.局部变量和PC计数器,同时又与其他协程共享全局变量和其他大部分东西 不同之处:一个多线程程序可以同时运行几个线程(并发执行.抢占),而协程却需要彼此协作地运行,并非真正的多线程,即一个多协程程序在同一时间只能运行一个协程,并且正在执行的协程只会在其显式地要求挂起(suspend)时,它的执行才会暂停(无抢占.无并发). 注意: Lua中的协程无法在外部将其停止,有可能导致程序阻塞 运行的是主线程时调用

Lua 学习笔记(九)协同程序(线程thread)

协同程序与线程thread差不多,也就是一条执行序列,拥有自己独立的栈.局部变量和命令指针,同时又与其他协同程序共享全局变量和其他大部分东西.从概念上讲线程与协同程序的主要区别在于,一个具有多个线程的程序可以同时运行几个线程,而协同程序却需要彼此协作的运行.也就是说多个协同程序在任意时刻只能运行一个协同程序,只有当正在运行的协同程序显式的要求挂起时,它的执行才会暂停. 一.协同程序coroutine Lua将所有关于协同程序的函数放置在一个名为“coroutine”的table中. 1.coro

Unity 中的协同程序

今天咱就说说,协同程序coroutine.(这文章是在网吧敲的,没有unity,但是所有结论都被跑过,不管你信得过我还是信不过我,都要自己跑一下看看,同时欢迎纠错)先说说啥是协程:协同程序是一个非常让人作呕的东西,它的表现形式非常像线程,对线程有过接触的朋友可能更理解我这句话的意思,你没接触过线程,那么理解它会有一些难度.但是它不存在线程安全问题,可以放心使用.这不是J哥信口雌黄空口白牙跟这猜的,事实是这样的:在操作系统层面,也就是更古老的大神们,觉得“并发”是一个很时髦的东西,很好使,于是他们

Unity3D中的Coroutine详解

Unity中的coroutine是通过yield expression;来实现的.官方脚本中到处会看到这样的代码. 疑问: yield是什么? Coroutine是什么? unity的coroutine程序执行流程怎么那么奇怪? unity中的coroutine原理是什么,怎么实现的? 使用unity的coroutine需要注意什么问题? 一.yield的在几种语言中的程序执行特性: Lua中的yield是使得协同函数运行->挂起并且传递参数给resume.resume使得协同函数挂起->运行