一。什么是协同程序

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

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

在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;
  }
 }
}

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

  1. Lua 协同程序(coroutine)

    什么是协同(coroutine)? Lua 协同程序(coroutine)与线程比较类似:拥有独立的堆栈,独立的局部变量,独立的指令指针,同时又与其它协同程序共享全局变量和其它大部分东西. 协同是非常 ...

  2. Unity3D协同程序(Coroutine)

    摘要下: 1. coroutine, 中文翻译"协程".这个概念可能有点冷门,不过百度之,说是一种很古老的编程模型了,以前的操作系统里进程调度里用到过,现在操作系统的进程调度都是根 ...

  3. 【转】关于Unity协同程序(Coroutine)的全面解析

    http://www.unity.5helpyou.com/2658.html 本篇文章我们学习下unity3d中协程Coroutine的的原理及使用 1.什么是协调程序 unity协程是一个能暂停执 ...

  4. Lua中的协同程序 coroutine

    Lua中的协程和多线程很相似,每一个协程有自己的堆栈,自己的局部变量,可以通过yield-resume实现在协程间的切换.不同之处是:Lua协程是非抢占式的多线程,必须手动在不同的协程间切换,且同一时 ...

  5. Lua中的协同程序 coroutine(转)

    Lua中的协程和多线程很相似,每一个协程有自己的堆栈,自己的局部变量,可以通过yield-resume实现在协程间的切换.不同之处是:Lua协程是非抢占式的多线程,必须手动在不同的协程间切换,且同一时 ...

  6. Lua 学习之基础篇九<Lua 协同程序(Coroutine)>

    引言 讲到协程,首先来介绍一下线程和协程的区别 lua协程和多线程 相同之处:拥有自己独立的桟.局部变量和PC计数器,同时又与其他协程共享全局变量和其他大部分东西 不同之处:一个多线程程序可以同时运行 ...

  7. Lua学习笔记4. coroutine协同程序和文件I/O、错误处理

    Lua学习笔记4. coroutine协同程序和文件I/O.错误处理 coroutine Lua 的协同程序coroutine和线程比较类似,有独立的堆栈.局部变量.独立的指针指令,同时又能共享全局变 ...

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

    协同程序与线程thread差不多,也就是一条执行序列,拥有自己独立的栈.局部变量和命令指针,同时又与其他协同程序共享全局变量和其他大部分东西.从概念上讲线程与协同程序的主要区别在于,一个具有多个线程的 ...

  9. Unity 中的协同程序

    今天咱就说说,协同程序coroutine.(这文章是在网吧敲的,没有unity,但是所有结论都被跑过,不管你信得过我还是信不过我,都要自己跑一下看看,同时欢迎纠错)先说说啥是协程:协同程序是一个非常让 ...

随机推荐

  1. java5初学

    1.Eclipse快捷键 alt + / 代码提示,例如自动创建main方法ctrl + d 删除当前行ctrl + alt + up/down 复制当前行alt + up/down 交换行ctrl ...

  2. 批量部署ssh免密登陆

    #!/bin/bash#set -xservers="10.254.192.xx10.254.192.xx10.254.192.xx"passwd="xxxxxxxx&q ...

  3. 解决IE浏览器中出现“Resource interpreted as Document but transferred with MIME type application/json”问题

    在上传图片时,使用ajax提交,返回的数据格式为json.在测试时发现IE浏览器中,上传图片后,没有显示图片,而是弹出一个提示:是否保存UploadImg.json文件:而在其他浏览器中正常. 在Ch ...

  4. hdu 1242 Rescue (BFS)

    Rescue Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Subm ...

  5. mplab xIde 编译成功,但不能生成Hex文件

    设置不对 如果还不行,在设置下面

  6. [HNOI2015][bzoj4009] 接水果 [整体二分+扫描线]

    题面 传送门 思路 本题其实有在线做法......但是太难写了,退而求其次写了离线 基本思路就是,考虑一个盘子以及它能接到的所有水果 可以发现,这个水果的端点一定在这个盘子两端的"子树&qu ...

  7. BZOJ 2458: [BeiJing2011]最小三角形 | 平面分治

    题目: 给出若干个点 求三个点构成的周长最小的三角形的周长(我们认为共线的三点也算三角形) 题解: 可以参考平面最近点对的做法 只不过合并的时候改成枚举三个点更新周长最小值,其他的和最近点对大同小异 ...

  8. UOJ356 【JOI2017春季合宿】Port Facility

    暴力就是O(n^2)连边,二分图,这样只有22分. 我们考虑优化建边,我们按照左端点排序,对于一个新加进来的线段,我们向左端点距其最近的和他相交的线段连边,别的相交的我们连同色边,当一个点连了两条同色 ...

  9. 身为多年的ubuntu用户。。。

    在这之前 说是多年也没有多年,事实上也就两年.. 不得不说一句,终于承受不住不稳定之重了... 个人觉得开始还是从centos开始比较好,比如说现在的我.. 之前看过的不知道在哪里的文章,谈论的是ub ...

  10. linux下有的目录有可执行权限

    在linux里面,目录也是一个文件.权限设置方法与普通文件一样.目录的可执行权限:目录无所谓执行不执行,目录只能否被开启(也称作“遍历”或“搜索”)对目录的执行权限不仅意味着查看目录下文件名还允许查看 ...