http://blog.csdn.net/nizihabi/article/details/47606887函数
1、Coroutine(协程)的概念和本质
在网上的一些资料当中,一直将Coroutine看成一个线程来描述,这样是不许确的。由于Coroutine并非一个新的线程,它仍旧是属于主线程的一部分。Coroutine本质上是一种轻量级的thread,它的开销会比使用thread少不少。多个Coroutine能够按照次序在一个thread里面执行,一个Coroutine若是处于block状态,能够交出执行权,让其余的Coroutine继续执行。性能
而在Unity当中,Coroutine是在全部的Update函数执行完成以后才开始执行的,也就是在LateUpdate()以后执行,主要是用来协助主线程进行工做,就像手动添加了一个另外的update()函数在里面同样,通常状况下咱们用于延时触发的功能。下面是关于MonoBehavior的执行顺序图,能够看到Coroutine是在LateUpdate以后的。spa

而咱们注意到上图中,Coroutine左边标注着几个yield模块,这个就是咱们下面要讲的如何使用Coroutine里的内容了。.net
2、Coroutine的使用
在Untiy里面,若是想要将一个函数Fun做为一个Coroutine使用,有两点是须要注意的
一、Fun的返回类型要为IEnumerator
二、yield的使用
yield ,在Coroutine里面更像是一个红绿灯的做用,在知足紧跟在它后面的条件以前,这个协程会挂起,把执行权交给调用它的父函数,知足条件时就能够执行yield下面的代码。你们能够执行一下下面的代码看看效果
- using UnityEngine;
- using System.Collections;
-
- public class ExampleClass : MonoBehaviour
- {
- IEnumerator WaitAndPrint()
- {
-
- yield return new WaitForSeconds(5);
- print("WaitAndPrint " + Time.time);
- }
- IEnumerator Start()
- {
- print("Starting " + Time.time);
-
-
- yield return StartCoroutine("WaitAndPrint");
- print("Done " + Time.time);
- }
- }
你们应该能获得下面的输出(本人的Unity版本是5.0.1f1)
另外你们能够再执行一下下面的代码,能够观察一下看看跟上面的有何异同
- using UnityEngine;
- using System.Collections;
-
- public class ExampleClass : MonoBehaviour
- {
- IEnumerator WaitAndPrint()
- {
-
- yield return new WaitForSeconds(5);
- print("WaitAndPrint " + Time.time);
- }
- void Start()
- {
- print("Starting " + Time.time);
-
-
- StartCoroutine("WaitAndPrint");
- print("Done " + Time.time);
- }
- }
获得的输出以下:
从上面能够看到,咱们是经过StarCoroutine的方法来启动一个新的Coroutine的,在第一段代码当中,把Start方法也声明成一个IEnumerator类型的时候,当执行到yield 模块,就会进行阻塞,等待yield模块完成了以后再继续往下执行,而声名成普通类型的时候,当启动了新的Coroutine的时候,遇到yield了,并不会把整个Start阻塞,而是会记录下当前执行的位置,而后返回父函数中执行,每一帧事后会检测yield是否知足,当知足yield条件,则返回到yield后面执行。
在Unity3D中,使用StartCoroutine(string methodName)和StartCoroutine(IEnumerator routine)均可以开启一个线程。区别在于使用字符串做为参数能够开启线程并在线程结束前终止线程,相反使用IEnumerator 做为参数只能等待线程的结束而不能随时终止(除非使用StopAllCoroutines()方法);另外使用字符串做为参数时,开启线程时最多只能传递一个参数,而且性能消耗会更大一点,而使用IEnumerator 做为参数则没有这个限制。
在Unity3D中,使用StopCoroutine(string methodName)来终止一个协同程序,使用StopAllCoroutines()来终止全部能够终止的协同程序,但这两个方法都只能终止该MonoBehaviour中的协同程序线程
还有一种终止Coroutine的方法,将gameObject的active属性设为False,可是设回true的时候并不会启动Coroutine。协程
注意:将Coroutine所在的脚本设为enable = false并不可以将Coroutine中止,由于它跟Monobehavior是同层级的。blog