博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Unity自己实现协程调度
阅读量:6040 次
发布时间:2019-06-20

本文共 1716 字,大约阅读时间需要 5 分钟。

自己实现协程调度有几个好处:

  1. 脱离Unity独立,拿到别的地方也可以用。
  2. 非主线程也可以启动协程,然后在主线程执行,比如异步网络消息等。
  3. 可以给每个协程一个id,通过id随时启动或关闭某个特定的协程,或者非MonoBehavior对象也可以管理属于自己的协程。

 

Unity中,Coroutine是在LateUpdate执行的,每一个update都会执行一部分代码,拿IEnumerator来说,就是每一次都会MoveNext一下。

IEnumerator有三个接口:

  • Current:返回一个object,可以设置当前的一个状态。
  • MoveNext:返回true表示没有到最后,返回false表示已经完成枚举。
  • Reset:恢复状态,从头开始枚举。

 

IEnumerator方法内部会有一个状态机的实现 ,如果StartCoroutine一个返回IEnumerator方法,每次就会MoveNext到一个yield,遇到yield return,MoveNext会返回true,Current值就是return的对象(yield return null时Current=null, yield return obj时Current=obj),遇到yield break,MoveNext会返回false,表示已经执行完毕。但是如果直接调用IEnumerator.MoveNext,不会去对里面的另一个协程MoveNext,下次就跳过了。

 

基于以上内容,可以自己写一个方法对IEnumerator进行MoveNext,以实现自制协程的核心代码:

public static bool MoveNext(IEnumerator subTask){  var child = subTask.Current;  //yield return另一个协程:递归MoveNext  if (child != null && child is IEnumerator && MoveNext(child as IEnumerator))    return true;  #if UNITY  //yield return www:等待www完成  if(child is UnityEngine.WWW && !(child as UnityEngine.WWW).isDone)    return true;  #endif  if (subTask.MoveNext ())    return true;   return false;}

 

管理协程很简单,用一个链表来管理:

LinkedListNode
node = m_taskList.First;LinkedListNode
tempNode = node;while (node != null) {   if (!MoveNext(node.Value)) {
    tempNode = node; node = node.Next; //此处可以写删除节点的后续处理 m_taskList.Remove(tempNode); } else { node = node.Next; } }

 

自己写IEnumerator方法时,return另一个协程不用写yield return StartCoroutine(func()),直接写yield return func()就可以,如:

IEnumerator a(){  ...}IEnumerator b(){  ...  yield return a();  ...}

 

也可以自己写一些实用的IEnumerator类,比如我们项目里用的WaitForEvent, 还有组合类如WaitForAll,WaitForAny等。

转载于:https://www.cnblogs.com/drashnane/p/6368307.html

你可能感兴趣的文章
走在网页游戏开发的路上(六)
查看>>
nginx 配置的server_name参数(转)
查看>>
Uva592 Island of Logic
查看>>
C++基础代码--20余种数据结构和算法的实现
查看>>
footer固定在页面底部的实现方法总结
查看>>
nginx上传文件大小
查看>>
HDU 2243 考研路茫茫——单词情结(自动机)
查看>>
Dubbo OPS工具——dubbo-admin & dubbo-monitor
查看>>
Dungeon Master ZOJ 1940【优先队列+广搜】
查看>>
Delphi 中的 XMLDocument 类详解(5) - 获取元素内容
查看>>
2013年7月12日“修复 Migration 测试发现的 Bug”
查看>>
学习vue中遇到的报错,特此记录下来
查看>>
CentOS7 编译安装 Mariadb
查看>>
jstl格式化时间
查看>>
一则关于运算符的小例
查看>>
centos7 ambari2.6.1.5+hdp2.6.4.0 大数据集群安装部署
查看>>
cronexpression 详解
查看>>
一周小程序学习 第1天
查看>>
小孩的linux
查看>>
SpringMVC、MyBatis声明式事务管理
查看>>