Unity3D-协同程序

协同程序

    unity协程是一个能暂停执行,暂停后立即返回,直到中断指令完成后继续执行的函数。它类似一个子线程单独出来处理一些问题,性能开销较小,但是他在一个MonoBehaviour提供的主线程里只能有一个处于运行状态的协程。主要用于处理一些耗时的异步操作,如网络访问IO访问等等。本文主要介绍了协同程序的概念及用法。

 

特点

1、协程在中断指令(YieldInstruction)产生时暂停执行
2、协程一暂停执行便立即返回 //中断协程后返回主函数,暂停结束后继续执行协程剩余的函数。
3、中断指令完成后从中断指令的下一行继续执行
4、同一时刻、一个脚本实例中可以有多个暂停的协程,但只有一个运行着的协程
5、函数体全部执行完后,协程结束
6、协程可以很好的控制跨越一定帧数后执行的行为
7、协程在性能上、相比于一般函数几乎没有更多的开销


概念理解

    Unity3D通过StartCoroutine()函数调用协程函数,协程函数里面必须包含yield return关键字。当程序执行到yield return关键字的时候:主线程返回调用协程函数的地方,知道yield return所在的语句执行完毕。一个协程的执行可以在任何地方用yield语句来暂停,yield return的值决定了什么时候协程恢复执行。协程在协调在几帧中执行的操作时有极大的用处,协程几乎没有任何性能开销。协程函数有固定的格式如下:

   IEnumerator methodName(Object parameter1,Object parameter2,...){
        // to do something
        yield return YieldInstruction/other/null;
        // to do something else
    }

示例:

1.png

这个程序非常清晰的表明,当StartCoroutine刚调用的时候,就是正常的函数调用,直到程序执行到yield return null(暂停协程,等待下一帧继续执行)时。yield return 返回的语句是异步执行的,执行完那个语句之后在接着在主线程继续执行yield return后面的东西。在执行yeild return 期间,主线程执行协程函数被调用地方的后面的语句。

 

yield return的用法

yield return 加不同的语句可以实现不同的功能,常用的协程函数用法:

yield return new WaitForSeconds(3.0f); // 等待3秒,然后继续从此处开始,常用于做定时器
yield return null; // 这一帧到此暂停,下一帧再从暂停处继续,常用于循环中
yield return new WaitForEndOfFrame(); // 等到这一帧的cameras和GUI渲染结束后再从此处继续,即等到这帧的末尾再往下运行。这行之后的代码还是在当前帧运行,是在下一帧开始前执行,跟return null很相似
yield return new WaitForFixedUpdate(); // 在下一次执行FixedUpdate的时候继续执行这段代码,即等一次物理引擎的更新
yield return www; // 等待直至异步下载完成
yield break; // 直接跳出协程,对某些判定失败必须跳出的时候,比如加载AssetBundle的时候,WWW失败了,后边加载bundle没有必要了,这时候可以yield break跳出。
yield return StartCoroutine(methodName); // 等待另一个协程执行完。这是把协程串联起来的关键,常用于让多个协程按顺序逐个运行。


协程函数的启动和停止

通过MonoBehaviour提供的StartCoroutine方法来实现启动协同程序。

1StartCoroutine(IEnumerator routine);

优点:灵活,性能开销小。缺点:无法单独的停止这个协程,如果需要停止这个协程只能等待协同程序运行完毕或则使用StopAllCoroutine();方法。

 

2StartCoroutine (methodName:string, value : object = null);

优点:可以直接通过传入协同程序的方法名来停止这个协程:StopCoroutine(string methodName);

缺点:性能的开销较大,只能传递一个参数。

 

以下三个方法可以停止协同程序:

1StopCoroutine(string methodName);

2StopAllCoroutine();

3、设置gameobjectactivefalse时可以终止协同程序,但是再次设置为true后协程不会再启动。

  

协同程序的执行顺序

开始协同程序 -> 执行协同程序 -> 中断协同程序(中断指令)-> 返回上层继续执行->中断指令结束后继续执行协同程序剩下的内容。

一个协程A里在中断指令里再启动一个协程B,yield return StartCoroutine时执行的顺序是:

①:先执行新协程B

②:新协程B暂停后向上返回协程AA协程暂停,返回协程A的上层函数;

③:因为决定协程A是否结束的标志是新协程B是否结束,所以当新协程B结束后返回协程A继续执行余下的内容;

 

 

协同程序的注意事项

1、不能再Update或者FixUpdate方法中使用协同程序,否则会报错。

2、关于中断指令:中断指令/YieldInstruction,一个协程收到中断指令后暂停执行,返回上层执行同时等待这个指令达成后继续执行。

 指令                      描述                          实现
 
WaitForSeconds       等待指定秒数        yield return new WaitForSeconds(2);
 
WaitForFixedUpdate     等待一个固定帧       yield return new WaitForFixedUpdate();
 
WaitForEndOfFrame      等待帧结束          yield return new WaitForEndOfFrame();                        
 
StartCoroutine       等待一个新协程暂停     yield return StartCoroutine(other coroutine);
 
WWW             等待一个加载完成      yield return www;

     关于WWW的中断指令可参考API:你可以检查isDone属性来查看是否已经下载完成,或者yield自动等待下载物体,直到它被下载完成(不会影响游戏的其余部分)。

 

协同程序的中断返回机制也可用于指定时间间隔执行一个程序:

//每3秒执行一次
while(true){
  //to do something
  yield return new WaitForSeconds(3);
}

 

 

参考文献:

[1]CSDN博客:霍莉雪特简单总结协程CoroutineYield常见用法.https://blog.csdn.net/qq_18995513/article/details/51944602.2016-07-18

[2]Unity3D学习网. 关于Unity协同程序(Coroutine)的全面解析.http://www.unity.5helpyou.com/2658.html.2015-3-21


上一篇: 没有了
下一篇:

首页 所有文章 机器人 计算机视觉 自然语言处理 机器学习 编程随笔 关于