相关链接:
http://dsqiu.iteye.com/blog/2029701
http://www.cocos2dev.com/?p=496
http://7dot9.com/?p=605
http://7dot9.com/?paged=2
开启与关闭协程:
using UnityEngine; using System.Collections; public class TestCoroutine : MonoBehaviour { void Start () { StartCoroutine("PrintA");//最多只能传递一个参数,并且性能消耗会更大一点 //StopCoroutine("PrintA"); IEnumerator b = PrintB(); StartCoroutine(b); //StopCoroutine(b); //StopCoroutine(PrintB());//不能关闭 //StopAllCoroutines();//只能关闭这个脚本的协程 } IEnumerator PrintA() { yield return new WaitForSeconds(1); print("A"); } IEnumerator PrintB() { yield return new WaitForSeconds(1); print("B"); } }
using UnityEngine; using System.Collections; public class TestCoroutine2 : MonoBehaviour { void Start () { //StartCoroutine(PrintC()); //gameObject.SetActive(false);//可以关闭协程 StartCoroutine(PrintD()); this.enabled = false;//不可以关闭协程 } IEnumerator PrintC() { yield return new WaitForSeconds(1); print("C"); } IEnumerator PrintD() { yield return new WaitForSeconds(1); print("D"); } }
using UnityEngine; using System.Collections; //yield return 代码段返回 0 或者 null 的意思就是告诉 Unity 等下一帧再从这里开始执行这个方法 //在 Wait() 方法成功执行返回之前不继续执行 SaySomeThings() 方法中的代码, //等到 Wait() 方法执行结束之后再继续执行 public class TimerExample : MonoBehaviour { void Start() { StartCoroutine(SaySomeThings()); } //Say some messages separated by time IEnumerator SaySomeThings() { Debug.Log("The routine has started"); yield return StartCoroutine(Wait(1.0f)); Debug.Log("1 second has passed since the last message"); yield return StartCoroutine(Wait(2.5f)); Debug.Log("2.5 seconds have passed since the last message"); } //Our wait function IEnumerator Wait(float duration) { for (float timer = 0; timer < duration; timer += Time.deltaTime) yield return 0; } }
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
一、通过设置MonoBehaviour脚本的enabled对协程是没有影响的,但如果 gameObject.SetActive(false) 则已经启动的协程则完全停止了,即使在Inspector把gameObject 激活还是没有继续执行。也就说协程虽然是在MonoBehvaviour启动的(StartCoroutine)但是协程函数的地位完全是跟MonoBehaviour是一个层次的,不受MonoBehaviour的状态影响,但跟MonoBehaviour脚本一样受gameObject 控制,也应该是和MonoBehaviour脚本一样每帧“轮询” yield 的条件是否满足。那么,如果我们即想让gameObject隐藏掉,但又不想那个gameObject上的mono脚本的协同程序被强制停止的话,我们就可以让其他mono去开启协程,例如Manager.Instance.StartCoroutine(Show());,让一个单例类的mono去开启协程,因为一般挂上Manager脚本的物体是不会被隐藏掉的。
二、yield 后面可以有的表达式:
a) null - the coroutine executes the next time that it is eligible
b) WaitForEndOfFrame - the coroutine executes on the frame, after all of the rendering and GUI is complete
c) WaitForFixedUpdate - causes this coroutine to execute at the next physics step, after all physics is calculated
d) WaitForSeconds - causes the coroutine not to execute for a given game time period
e) WWW - waits for a web request to complete (resumes as if WaitForSeconds or null)
f) Another coroutine - in which case the new coroutine will run to completion before the yielder is resumed
值得注意的是 WaitForSeconds()受Time.timeScale影响,当Time.timeScale = 0f 时,yield return new WaitForSecond(x) 将不会满足。
如果想忽略Time.timeScale影响,可以使用Time.realtimeSinceStartup,具体可以看这里:http://blog.csdn.net/Fredomyan/article/details/44132719
三、协程其实就是一个IEnumerator(迭代器),IEnumerator 接口有两个方法 Current 和 MoveNext() ,只有当MoveNext()返回 true时才可以访问 Current,否则会报错。迭代器方法运行到 yield return 语句时,会返回一个expression表达式并保留当前在代码中的位置。 当下次调用迭代器函数时执行从该位置重新启动。Unity在每帧做的工作就是:调用 协程(迭代器)MoveNext() 方法,如果返回 true ,就从当前位置继续往下执行。
四、