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