Unity Learning for Coroutine(协程)

来源:互联网 发布:易观智库数据 编辑:程序博客网 时间:2024/06/08 15:17

Unity StartCoroutine 和 yield return 深入研究

StartCoroutine和yield return表面意思很好理解,StartCoroutine就是开启一个协程,yield return是迭代器块返回迭代调用的地方。

MonoBehaviour.StartCoroutine

public Coroutine StartCoroutine(IEnumerator routine);

Description

Starts a coroutine.

The execution of a coroutine can be paused at any point using the yield statement. The yield return value specifies when the coroutine is resumed. Coroutines are excellent when modelling behaviour over several frames. Coroutines have virtually no performance overhead. StartCoroutine function always returns immediately, however you can yield the result. This will wait until the coroutine has finished execution. There is no guarantee that coroutines end in the same order that they were started, even if they finish in the same frame.

意思是:一个协程的执行可以在任何地方用yield语句来暂停,yield return的值决定了什么时候协程恢复执行。协程在协调在几帧中执行的操作时有极大的用处.协程几乎没有任何性能开销。

StartCoroutine一般都会立即返回,然而你也可以获得返回结果的值。但是这一步会等到协程结束执行才能生效。

public class MainTest:MonoBehaviour {    void Start() {        Debug.Log("start1");        StartCoroutine(Test());        Debug.Log("start2");    }    IEnumerator Test()    {        Debug.Log("test1");        yield return null;        Debug.Log("test2");    }//运行结果    start1    test1    start2    test2
void Start () {        Debug.Log("start1");        StartCoroutine(Test());        Debug.Log("start2");    }    IEnumerator Test()    {        Debug.Log("test1");        yield return StartCoroutine(DoSomething());        Debug.Log("test2");    }    IEnumerator DoSomething()    {        Debug.Log("load 1");        yield return null;        Debug.Log("load 2");    }//执行结果:start1test1load1start2load2test2

这种StartCoroutine中嵌套一个yield return StartCoroutine,第一个StartCoroutine会等到第二个StartCoroutine中所有代码结束后再继续执行,而第二个StartCoroutine中的yield语句会先返回第一个,然后立即返回他的调用处,也就是调用处会继续执行,而第一个StartCoroutine会等待第二个执行完再继续执行。

如果还想继续深入,可以看一下C#中的迭代器,那里面说明了yield和IEnumerator根本到底是什么。

总结

协程是一种更加灵活的Update()替代品,避免过多的游戏逻辑堆砌在一个Update()中导致最终的可读性下降。同时还提供了yield return new WaitForSeconds(float)这样方便的等待功能,不需要在外部申明一堆计时器变量然后在逻辑中使用if()else()判断时间这样繁琐的流程。

另外,协程也存在一些问题,就是启用多个协程之后,务必注意代码执行顺序的问题,这个问题在以前可以使用Update()和LateUpdate()缓解,但是在协程里就不太好解决,所以尽量避免多个协程之间的耦合,在一个协程中完成一个独立的功能是一个良好的思路。


学习参考:
1、http://www.unity.5helpyou.com/2658.html
2、异步编程http://www.ruanyifeng.com/blog/2012/12/asynchronous%EF%BC%BFjavascript.html
3、协程http://gypsumlabs.github.io/2015/12/08/unity-tips-coroutine/

原创粉丝点击