一。什么是协同程序

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

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

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

最新文章

  1. Flavors
  2. ubuntu 修改保存报错E37:No write since last change(add ! to override)的解决方法
  3. 对thinkphp静态模板表单提交的理解
  4. 访问网页时提示的503错误信息在IIS中怎么设置
  5. 在centos 6.5 在virtual box 上 安装增强版工具
  6. [POJ 2356] Find a multiple
  7. Oracle-PLSQL Developer使用笔记
  8. SQL语句 远程操作数据库
  9. 《开源分享2》:《开源框架实战宝典电子书V1.0.0》完整版!
  10. Json之语法,格式
  11. (中等) HDU 4370 0 or 1,建模+Dijkstra。
  12. Angular记录(5)
  13. 2019 蓝桥杯省赛 A 组模拟赛(一)-修建公路
  14. 【简书】在阿里云自带的CentOS + LAMP环境下部署一个Laravel项目
  15. php 配置xdebug
  16. python+selenium+Jenkins构建自动化测试
  17. 51Nod 算法马拉松28 A题 先序遍历与后序遍历 分治
  18. ubuntu安装jupyter 并设置远程访问
  19. h.264 x.264
  20. 【转】每天一个linux命令(3):pwd命令

热门文章

  1. Grid 布局管理器
  2. create vm
  3. leetcode 201. 数字范围按位与 解题报告
  4. Python——初识Python
  5. static_cast AND dynamic_cast
  6. 后端model传入前端JSP页面中的值判断后再取值
  7. intellij idea 2017 工具使用问题
  8. Codeforces 846D Monitor(简单二分+二维BIT)
  9. 洛谷 P3765 总统选举 解题报告
  10. 【BZOJ 4057 Kingdoms】