參考博客:
http://www.unity.5helpyou.com/2658.html
什麼是協程?(又稱協同程序)
協程類似於函數,可以暫停執行(yield return xxx 之後的代碼) , 在下一幀時再次判斷是否繼續執行。
協程不是多線程,它與主線程同時運行,它在主線程運行的同時開啓另一段邏輯處理,類似一個子線程單獨出來處理一些問題,性能開銷較小,,Unity的協程會在每幀結束之後去檢測yield的條件是否滿足,滿足則執行yield return之後的代碼。
在一個MonoBehaviour提供的主線程裏只能有一個處於運行狀態的協程,而其他協程處於休眠狀態。協程實際上是在一個線程中,只不過每個協程對CUP進行分時,協程可以訪問和使用unity的所有方法和component。
(1)協程的定義:
IEnumrator 函數名(形參表) //最多隻能有一個形參
{
yield return xxx;
}
(2)關於協程的開啓和停止這裏就不再贅述了,網上很多資料。
(3)關於協程的中斷指令,即 yield return 後面的指令
yield break; 停止協程
yield return www; 等待一個WWW加載完成
yield return 0/null/數字; 暫停一幀,一般使用null
yield return new WaitForSeconds(時間); 等待指定秒數(受時間縮放係數的影響)
yield return new WaitForFixedUpdate(); 等待一個固定幀(物理更新,在FixedUpdate之後執行)
yield return new WaitForEndOfFrame(); 等待一幀結束(在OnGUI後執行)
yield return StartCoroutine(other coroutine); 暫停執行,等待另一個協程完成
yield return new WaitUntil(返回值爲bool類型的函數名);等待直到條件爲真時
yield return new WaitWhile(返回值爲bool類型的函數名);等待直到條件爲假時
(4)關於協程的流程:實例-加載指令(通過WWW加載本地文件)
private string path = “file://F:/Resource/Dragon.unity3d”;
void OnGUI(){
if(GUI.Button(new Rect(200,200,150,30),”點擊進入協同程序”)){
Debug.Log(“1”);
StartCoroutine(loadLocalBundle(path));
Debug.Log(“3”);
}
}
private IEnumerator loadLocalBundle(string url){
using(WWW www = new WWW(url)){
yield return www;
//判斷加載資源是否出錯
if(www.error != null){
var bytes = www.bytes;
}
//加載完AssetBundle資源包後,實例化物體
AssetBundle ab = www.assetBundle;
GameObject gameObject = ab.mainAsset as GameObject;
Instantiate(gameObject);
}
}
注意:
大概執行流程,點擊按鈕後開始執行協同程序,WWW按照提供的url進行加載,www在加載完成後跳出中斷繼續執行yield return www餘下內容,判斷加載的資源是否出錯 和 實例化加載內容
協程實現一個倒計時:
IEnumerator CountDown(int time)
{
for(int t = time;t >= 0;t -= 1)
{
print(time);
time -= 1;
yield return new WaitForSecondsRealtime(1f); //WaitForSecondsRealtime不受時間縮放影響
}
}