一。什么是协同程序

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

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

在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. shell监控脚本

    序言: 前几天一好友问我服务器监控怎么做?你们公司的监控是怎么做的?有什么开源的监控软件推荐?常见的开源的监控软件当然首先推荐ZABBIX,分布式够强大,而且很多公司都在用,我问他具体什么需求,能监控 ...

  2. hnust py road

    问题 C: Py Road 时间限制: 1 Sec  内存限制: 128 MB提交: 125  解决: 34[提交][状态][讨论版] 题目描述 Life is short,you need Pyth ...

  3. 软工实践Alpha冲刺(9/10)

    v队名:起床一起肝活队 组长博客:博客链接 作业博客:班级博客本次作业的链接 组员情况 组员1(队长):白晨曦 过去两天完成了哪些任务 描述: 已经解决登录注册等基本功能的界面. 完成非功能的主界面制 ...

  4. myEclipse如何将程序部署到tomcat(附录MyEclipse调试快捷键)

    部署 1.选中你要部署的项目,在工具栏找到 Deploy MyEclipse J2EE Project to Server 2.单击Add,即出现如下界面.选择相应的Server,要和你在配置tomc ...

  5. kvm搭建完成了,那么问题来了,到底是什么原理

    kvm中到底是怎么模拟的CPU和内存? 收到了大量的 这里有一个裸的调用kvm接口的实例,超赞: http://www.cnblogs.com/Bozh/p/5753379.html 使用kvm的AP ...

  6. BZOJ3594 [Scoi2014]方伯伯的玉米田 【树状数组优化dp】

    题目链接 BZOJ3594 题解 dp难题总是想不出来,, 首先要观察到一个很重要的性质,就是每次拔高一定是拔一段后缀 因为如果单独只拔前段的话,后面与前面的高度差距大了,不优反劣 然后很显然可以设出 ...

  7. echarts移动端字体模糊解决方法

    echarts使用canvas画图,在移动端使用rem时候,若viewport的scale被缩放,则字体会发生模糊,本人采用的解决方法是在不同的dpr下使用不同的字体大小,具体代码如下: 获取字体大小 ...

  8. ubuntu安装出现"删除initramfs-tools时出错",subprocess installed post-installation script returned error exit status 1

    昨日准备重装ubuntu,增大了系统容量,因为前面用到boot分区不到100M,于是这里分区如下 /boot 100M / 30G /home 50G 然后安装快结束时就出现如下图问题 开始以为是镜像 ...

  9. altera ip 核小究

    用quartus的MegaWizard工具生成一个乘法器multiplier,会在工程目录下产生 multiplier.qip    (可选) multiplier_bb.v  (可选) multip ...

  10. es6+最佳入门实践(4)

    4.函数扩展 4.1.参数默认值 默认参数就是当用户没有传值的时候函数内部默认使用的值,在es5中我们通过逻辑运算符||来实现 function Fn(a, b) { b = b || "n ...