StartCoroutine和yield return表面意思很好理解,StartCoroutine就是開啓一個協程,yield return 是迭代器塊返回調用迭代的地方。html
是吧?不知道你什麼感受,反正我以爲,仍是須要深刻研究一下的。OK,here we go!函數
首先,先看一下StartCoroutine在Unity官方的解釋。性能
意思是:一個協程的執行能夠在任何地方用yield語句來暫停,yield return的值決定了何時協程恢復執行。協程在協調在幾幀中執行的操做時有極大的用處.協程幾乎沒有任何性能開銷。spa
StartCoroutine通常都會當即返回,然而你也能夠得到返回結果的值。可是這一步會等到協程結束執行才能生效。3d
OK,意思應該不難理解,根據他的意思咱們來分析一段程序。code
運行結果是:協程
start1htm
test1blog
start2get
test2
這下就一目瞭然了,當StartCoroutine剛調用的時候,能夠理解爲正常的函數調用,而後接着看調用的函數裏面。
當被調用函數執行到yield return null;(暫停協程,等待下一幀繼續執行)時,根據Unity解釋協同程序就會被暫停,其實我我的認爲他這個解釋不夠精確,先返回開始協程的地方,而後再暫停協程。也就是先通知調用處,「你先走吧,不用管我」,而後再暫停協程。。怎麼?不信?那咱們再寫個demo驗證一下。
執行結果:
start1
test1
start2
test2 (這個test2是等待三秒後纔打印出來的)
正好順便驗證了「yield return的值決定了何時協程恢復執行」這句,其實yield return後面的值能夠後不少用法,能夠看這個帖子:http://blog.sina.com.cn/s/blog_aaa4ce8d010131kr.html
其實再回過頭來想一想,協程->協同程序->其實就是協同兩個任務,表面看起來很簡單,可是在一些稍微大點的項目中用起來,對於新手來講仍是會有些晦澀。。。
好比說
IEnumerator Init() { yield return StartCoroutine(init1()); Debug.Log("init1 finish"); yield return StartCoroutine(init2()); Debug.Log("init2 finish"); yield return StartCoroutine(init3()); Debug.Log("init3 finish"); } IEnumerator init1() { // 模擬初始化 yield return new WaitForSeconds(2);// } IEnumerator init2() { // do somthing.. yield return new WaitForSeconds(2);// } IEnumerator init2() { // do somthing.. yield return new WaitForSeconds(2);// }
其實就是一個執行順序的問題,這樣調用能保證,init1,init2,init3一個一個的執行,不至於出現後面執行的代碼引用一個前面未初始化的變量。。。
那麼,接着這個執行順序的話題,咱們在來研究一個話題,看下面代碼
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"); }
執行結果:
start1
test1
load1
start2
load2
test2
這種StartCoroutine中嵌套一個yield return StartCoroutine,第一個StartCoroutine會等到第二個StartCoroutine中全部代碼結束後再繼續執行,而第二個StartCoroutine中的yield語句會先返回第一個,而後當即返回他的調用處,也就是調用處會繼續執行,而第一個StartCoroutine會等待第二個執行完再繼續執行。
若是還想繼續深刻,能夠看一下C#中的迭代器,那裏面說明了yield和IEnumerator根本究竟是什麼。
OK,今天就說到這。Good Luck!