Coroutine,翻译过来叫协程,这东西在 as3 里面没有,所以觉得挺新鲜的,顾做点研究.
Unity 里面的 Coroutine 通过关键字 yield 来定义的(Unity Coroutine),所以我们先看这个关键字.
先上一张高大上的 unity 运行时序图
yield 关键字
yield 是 C#定义的一个关键字,相关文档(C# yield)
使用 yield return 语句可一次返回一个元素。
通过 foreach 语句或 LINQ 查询来使用迭代器方法。 foreach 循环的每次迭代都会调用迭代器方法。 迭代器方法运行到 yield return 语句时,会返回一个 expression,并保留当前在代码中的位置。 当下次调用迭代器函数时执行从该位置重新启动。
可以使用 yield break 语句来终止迭代。
例子
输出
结论
包含 yield 的语句在每次遍历的时候执行一次并停止,在下次遍历时恢复并继续
unity 中的协程
相关文档
Unity StartCoroutine
Unity StopCoroutine
例子
输出
结论(没有源码,都是推论)
在第一个例子中,我们手动用了 while 循环对迭代器进行迭代
Unity 利用函数StartCoroutine
把这个迭代过程分发给了每帧去执行
我们具体看代码,首先Start
函数被自动调用,开始执行第一行代码.
在第一行代码中,StartCoroutine
把函数yieldFun2()
函数里面的语句用 yield 分割成了三块.
第一块
第二块
第三块
这三块为被分割到了三个更新时间片去执行.首先第一块被直接执行,所以日志输出了
111/14/2014 14:34:57
并且在帧刷新中继续执行WaitForSeconds(1f);
程序此时不会因为等待一秒而挂起,而是返回主流程继续执剩余代码,日志输出
End yieldFun2
之后帧刷新中判断到达了一秒的等待时间,到了执行第二块,然后第三块..
协程的中断
例子
输出
结论
中断有两种,一种调用yield break
中断,一种调用StopCoroutine
,
test1
实现了第一种,test2
实现了第二种,
1:多个协程是同时进行的,看第一条和第二条输出的时间可知;
2:在调用 StartCoroutine 最好保存参数的引用,因为在嵌套调用时传引用能正确停止,但是调用StopCoroutine(yieldFun3())
是停止不掉的.已字符串的形式调用都能停止,而且停止全部相同的协程实例.
yield 返回值
这里的<expression>
在 Unity 中可以多种对象
例子
我这里用了两种 yield 返回值,第一种被我注释掉的直接返回 www 对象,第二种返回空如果运行起来就会发现第一种 progress 的 log 只打了一次,第二种会完成多次包含进度的数据,为什么?
因为上面说过了,如果 yield 返回的对象是 www,那么代码块结束的标志是 www 下载完毕,当 www 下载完毕的时候,www,isdown 一定是 true,所以跳出循环
而第二种返回基本对象会在帧刷新时间片里直接返回并等待下一个 yield 的执行,这样就对多次触发 www.isDone(除非网速超级快在一帧内下好了,那也可能只出一条)
上面说到的自定义返回对象我就不啰嗦了,有例子
自定义 coroutines1
自定义 coroutines2
结论
C#里面的 yield 返回一个迭代器,之后我们需要通过循环自己去迭代内容.
unity 利用 StartCoroutine 函数将返回的迭代器交给帧刷新分布执行,很有创意哦..