基本概念
Coroutine,概念上讲,有两点值得注意的:1.它是在主程序运行时同时开启另一段逻辑处理来协同当前程序的执行。2.开启协同程序就类似于开启一个线程,但是它又不是真正意义上的多线程。
实例讲解
下面为了快速理解,我用一个简单的实例来说说它的具体使用方法。
首先,没有用Coroutine的时候,我们要在鼠标点击一个Cube时让这个Cube的X方向移动到10然后回到原点,下面是代码,但是这样我们会发现点击鼠标以后没有任何效果,因为循环执行的太快了。
void OnMouseDown () { testMove (); } void testMove () { for (int i=0; i<100; i++) { transform.Translate(0.1f, 0f, 0f); } //回到原点 transform.position = new Vector3(0, 0, 0); Debug.Log("Completed Moving!"); }
要达到我们想要的效果,可能有人说可以在Update函数中执行移动的部分。没错,可以那么去做,但是也可以用Coroutine达到我们想要的效果。
再次,用Coroutine重新实现功能,我们就可以看到我们的Cube移动以后又回到原点。我先直接上代码,后面再做讲解。
void OnMouseDown () { StartCoroutine (testCoroutineMove()); } IEnumerator testCoroutineMove() { for (int i=0; i<100; i++) { transform.Translate(0.1f, 0f, 0f); yield return null; } //回到原点 transform.position = new Vector3(0, 0, 0); Debug.Log("Completed Moving!"); }这里我说三点,1.StartCoroutine;2.IEnumerator;3.yield。
1.StartCorountine,就是调用一个Coroutine函数的方法,除上面例子用的方法外,还可以用反射的方法调用,如:StartCoroutine("testCoroutineMove")。
2.IEnumerator,我们看到,Coroutine函数的返回值不是void了,其实,IEnumerator仅仅是一个返回类型,返回这种类型的函数我们就可以看出是Coroutine函数。
3.yield,字面意思是“放弃”,就是说执行这句这句话代表我要放弃继续执行。那什么时候继续执行呢?这就要看你后面return的是什么参数了,后面我会总结常用的一些返回参数,这里的null是指下一帧再继续执行。
附加实例
下面讲一个Coroutine的实际运用场景。比如说,我们在移动上面说的那个Cube之前我们需要加载一些资源之类的,如果我们加载资源的代码没有用Coroutine来实现,那么我们就会看到场景先卡顿一下然后才移动Cube。所以,我们就需要让加载场景的内容和移动Cube同时进行,下面就是实现的代码:
void OnMouseDown () { StartCoroutine (heavyTask()); StartCoroutine (testCoroutineMove()); } IEnumerator heavyTask() { float a = 0.0f; for (int i=0; i<100; i++) { a += 1.264564f; for (int j=0; j<100; j++) { a += 1.264564f; } yield return null; } Debug.Log("heavyTask Finished ! "); } IEnumerator testCoroutineMove() { for (int i=0; i<100; i++) { transform.Translate(0.1f, 0f, 0f); yield return null; } //回到原点 transform.position = new Vector3(0, 0, 0); Debug.Log("Completed Moving!"); }常用yield返回值
常用的有:null,WaitForSeconds,WaitForEndOfFrame,WaitForFixedUpdate,Another Coroutine,WWW
1.null
它是会挂起一帧,下一帧会继续执行。
2.WaitForSeconds
它的用法如:yield return new WaitForSeconds(2f);,这样就会让当前Coroutine函数挂起2秒。
3.WaitForEndOfFrame
它的用法和null是一样的效果。
4.WaitForFixedUpdate
它和null类似,但是不是一帧,而是一个Fixed帧时间。
5.Another Coroutine
这个就是可以在悬挂的时候执行另一个Coroutine函数,知道Another Coroutine执行完毕才会继续执行。
6.WWW
这个会挂起等待一个网络响应,完毕以后会继续执行。
最后,注意一点,最好将协同代码写在执行层面,避免一些不要的麻烦。