【Unity/筆記】協程Coroutine

協程


介紹

  • 不是進程或線程,執行過程類似於子例程或者說不帶返回值的函數調用。
  • 達到類似多線程的併發執行效果
  • 在yield return 處移交控制權。
  • 可以提前結束執行

使用

  • 聲明方式
    1. IEnumerator [methodName] (){yield return XXX }
    2. IEnumerator [methodName] (){yield return T }
  • 開啓方式

    1. public Coroutine StartCoroutine(IEnumerator methodName());
    2. public Coroutine StartCoroutine(string methodName);
    3. public Coroutine StartCoroutine(string methodName, [DefaultValue(“null”)] object value);

    StartCoroutine會立即執行開啓傳入的協程並返回一個Coroutine類型。

  • 結束方式

    1. public void StopCoroutine(IEnumerator methodName());
    2. public void StopCoroutine(string methodName);
    3. public void StopCoroutine(Coroutine routine);

      前兩種結束方式根據參數類型分別對應開啓方式的三種,第三種結束方式傳入參數爲StartCoroutine所返回的Coroutine類型實例。

      內部結束執行
      yield break;

  • 執行順序:開啓協程後會立即開始執行協程中的命令,直到遇到第一個yield return 時會暫時把控制權移交出去並繼續執行其它代碼,此時這個協程在這一幀中已經無法繼續往下執行了,下一幀開始後根據生命週期函數的執行順序去訪問一次協程,如果可以則會從上次yield return的地方繼續往下執行,以此類推。

    關於協程中各類yield return在一幀中執行的順序可以查閱Unity目錄下的Editor/Data/Documentation/en/Manual/ExecutionOrder.html的生命週期圖,也可通過Unity內幫助進行訪問。


協程本質

  • 協程的本質是迭代器,它們被封裝在IEnumerator,IEnumerable以及他們倆的泛型形式IEnumerator,IEnumerable之中。其中IEnumerator還實現了IDisposable接口。

    public interface IEnumerator
    {
    object Current { get; }
    bool MoveNext();
    void Reset();
    }
    public interface IEnumerable
    {
    IEnumerator GetEnumerator();
    }
    public interface IEnumerator : IEnumerator, IDisposable
    {
    T Current { get; }
    }
    public interface IEnumerable : IEnumerable
    {
    IEnumerator GetEnumerator();
    }
    public interface IDisposable
    {
    void Dispose();
    }

  • IEnumerable 用來獲取一個迭代器(IEnumerator),而迭代工作實際在IEnumerator中實現,這一過程可以通過代碼來模擬完成。

    1. 執行一個協程IEnumerator,將返回得到一個新類型實例 ,循環執行該實例的MoveNext方法,如果MoveNext返回true則打印出該實例的屬性Current,這樣可以看到在協程中yield return的值都被依次打印出來,這就是foreach方法所執行的大概過程。
    2. IEnumerable提供了一個GetEnumerator的方法用來獲取迭代器。
      3.協程中所返回的值被迭代器保存在堆上以便後面繼續使用,每次調用MoveNext()方法時會從上次yield return的地方繼續。
    3. 其實迭代器這種設計在多種主流語言中都可見到,如Java,ECMAScript,Python等,通常多使用於集合類數據結構的遍歷。

迭代器是什麼

  • 迭代器工作原理是使用狀態機,在迭代器創建完一個新類型且一次未調用MoveNext前,狀態機的狀態爲0(初始狀態),
  • 此後在迭代器每次狀態改變前的狀態都會被重置爲-1(預備狀態/結束狀態),
  • 然後執行過程中的代碼並記錄當前返回值,在一系列狀態完成之後狀態會依次變爲1,2,3,4…(完成狀態)以便記錄所執行到的位置。
  • 另外,由於IEnumerable還需額外執行GetEnumerator方法來獲取到IEnumerator,狀態機用-2(轉接狀態)來標記這一階段的狀態

參考資料:

  1. 《使用C#語言開發跨平臺遊戲》—陳嘉棟
  2. Unity官方文檔
發佈了27 篇原創文章 · 獲贊 7 · 訪問量 1萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章