【轉】關於Unity協同程序(Coroutine)的全面解析

http://www.unity.5helpyou.com/2658.htmlhtml

本篇文章咱們學習下unity3d中協程Coroutine的的原理及使用函數

1.什麼是協調程序性能

unity協程是一個能暫停執行,暫停後當即返回,直到中斷指令完成後繼續執行的函數。學習

它相似一個子線程單獨出來處理一些問題,性能開銷較小,可是他在一個MonoBehaviour提供的主線程裏只能有一個處於運行狀態的協程。url

2.協同程序的特色spa

一、協程在中斷指令(YieldInstruction)產生時暫停執行線程

二、協程一暫停執行便當即返回 //中斷協程後返回主函數,暫停結束後繼續執行協程剩餘的函數。3d

三、中斷指令完成後從中斷指令的下一行繼續執行rest

四、同一時刻、一個腳本實例中能夠有多個暫停的協程,但只有一個運行着的協程code

五、函數體所有執行完後,協程結束

六、協程能夠很好的控制跨越必定幀數後執行的行爲

七、協程在性能上、相比於通常函數幾乎沒有更多的開銷

 

3.建立一個協程函數

注意:

協同函數的返回值的類型必須是Coroutine,Coroutine繼承與Yieldinstruction。

因此協同程序的返回類型就只能是null,等待的時間,等待的幀數。。因而可知WWW 也是實現了Coroutine的~

4.開始一個協同程序

經過MonoBehaviour提供的StartCoroutine方法來實現啓動協同程序。

一、StartCoroutine(IEnumerator routine);

優勢:靈活,性能開銷小。

缺點:沒法單獨的中止這個協程,若是須要中止這個協程只能等待協同程序運行完畢或則使用StopAllCoroutine();方法。

二、StartCoroutine (methodName:string, value : object = null);

優勢:能夠直接經過傳入協同程序的方法名來中止這個協程:StopCoroutine(string methodName);

缺點:性能的開銷較大,只能傳遞一個參數。

5.中止協同程序

一、StopCoroutine(string methodName);

二、StopAllCoroutine();

三、設置gameobject的active爲false時能夠終止協同程序,可是再次設置爲true後協程不會再啓動。

6.協同程序的執行順序

開始協同程序 -> 執行協同程序 -> 中斷協同程序(中斷指令)-> 返回上層繼續執行

->中斷指令結束後繼續執行協同程序剩下的內容

7.協同程序的注意事項

一、不能再Update或者FixUpdate方法中使用協同程序,不然會報錯。

二、關於中斷指令:

中斷指令/YieldInstruction,一個協程收到中斷指令後暫停執行,返回上層執行同時等待這個指令達成後繼續執行。

 

  指令                      描述                          實現

WaitForSeconds          等待指定秒數            yield return new WaitForSeconds(2);

WaitForFixedUpdate      等待一個固定幀          yield return new WaitForFixedUpdate();

WaitForEndOfFrame       等待幀結束              yield return new WaitForEndOfFrame();                         

StartCoroutine          等待一個新協程暫停      yield return StartCoroutine(other coroutine);

WWW                     等待一個加載完成        yield return www;

注意:

一、一個協程A裏在中斷指令裏再啓動一個協程B,在yield return StartCoroutine時執行的順序是:

①:先執行新協程B;

②:新協程B暫停後向上返回協程A,A協程暫停,返回協程A的上層函數;

③:由於決定協程A是否結束的標誌是新協程B是否結束,因此當新協程B結束後返回協程A繼續執行餘下的內容;

④:協程A執行結束。

二、關於WWW的中斷指令可參考API:

You can inspect the isDone property to see if the download has completed or yield the download object to automatically wait until it is (without blocking the rest of the game).

你能夠檢查isDone屬性來查看是否已經下載完成,或者yield自動等待下載物體,

直到它被下載完成(不會影響遊戲的其他部分)。

三、協同程序的中斷返回機制也可用於指定時間間隔執行一個程序:

 

8.例子

lg一、舉例說明協同程序的執行流程

 

using UnityEngine;
using System.Collections;

public class SimpleCoroutine : MonoBehaviour {
/// <summary>
/// Start, 協程的執行流程
/// Start函數運行,輸出「1」,而後開始協程Do;
/// Do輸出「2」,而後開始協程newDo;
/// newDo輸出「3」,產生中斷指令後暫停,當即返回Do;
/// Do產生中斷指令後暫停,Do暫停並當即返回Start函數;
/// Start執行StartCoroutine的下一條語句:輸出「4」;
/// 2秒後,newDo的中斷指令完成並繼續執行,輸出「5」,協程newDo結束;
/// Do的中斷指令由於協程newDo的結束而完成並繼續執行,輸出「6」,協程Do結束。
/// </summary>
void Start () {
Debug.Log(「1」);
StartCoroutine(Do());
Debug.Log(「4」);
}
IEnumerator Do() {
Debug.Log(「2」);
yield return StartCoroutine(newDo());//WaitForSeconds(5);
Debug.Log(「6」);
}
IEnumerator newDo() {
Debug.Log(「3」);
yield return new WaitForSeconds(2);
Debug.Log(「5」);
}
}
//輸出結果順序是,1,2,3,4,5,6

[/csharp]

lg二、加載指令(經過WWW加載本地文件)

?
1
 

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){Debug.Log(「2」);using(WWW www = new WWW(url)){yield return www;Debug.Log(「4」);if(www.error != null){var bytes = www.bytes;}AssetBundle ab = www.assetBundle;GameObject gameObject = ab.mainAsset as GameObject;Instantiate(gameObject);Debug.Log(「5」);Debug.Log(「load local assetBundle finished…」+gameObject);}}注意:大概執行流程,點擊按鈕後開始執行協同程序,WWW按照提供的url進行加載,完畢後 yield return www;中斷指令跳轉到主線程。主線程繼續執行其餘內容,www在加載完成後跳出中斷繼續執行餘下內容。加載完畢,實例化加載內容。

相關文章
相關標籤/搜索