Unity 協程用法總結

Unity 協程用法總結

協程:協同程序,在主程序運行的同時,開啓另外一段邏輯處理,來協同當前程序的執行,注意協程不是線程,只是具有線程特點的“僞協程”。
協程的使用需要直接或間接的繼承MonoBehavior。

協程的執行原理

協程函數的返回值必須是IEnumerator,它是一個迭代器,可以把它當成執行一個序列的某個節點的指針,它提供了兩個重要的接口,分別是Current(返回當前指向的元素)和MoveNext(將指針向後移動一個單位,如果移動成功,則返回true)。

yield關鍵詞用來聲明序列中的下一個值或是一個無意義的值,如果使用yield return x(x是指一個具體的對象或數值),那麼MoveNext返回爲true並且Current被賦值爲x,如果使用yield break使得MoveNext()返回爲false。

如果MoveNext函數返回爲true意味着協程的執行條件被滿足,則能夠從當前的位置繼續往下執行。否則不能從當前位置繼續往下執行。

協同方法與普通方法的區別:

普通方法被調用時,原來執行的部分保留現場,停止執行,然後去執行要調用的方法,等待被調用的方法執行完之後才繼續執行調用前的方法。
協同方法的執行是不用等協同方法執行完再執行調用之前原來方法的代碼,即協程可暫停,兩者異步執行。

開啓協程的兩種方式

1、StartCoroutine(string methodName) //參數爲方法名字符串
2、StartCoroutine(IEnumerator method) //參數是方法名,方法中可包含多個參數

終止協程的兩種方式:

StopCoroutine(string methodName) //只能終止以字符串形式啓動的協程
StopAllCoroutine() //終止所有協程

協程的返回值

協程必須有有返回值,且返回值類型爲IEnumrator。返回值語句爲yield retuen 表達式或值 或 yield break。
yield:掛起,程序遇到yield關鍵字時會被掛起,暫停執行,等待條件滿足時從當前位置繼續執行
yield return 0 or yield return null: 程序在下一幀中從當前位置繼續執行
yield return 1,2,3,…: 程序等待1,2,3…幀之後從當前位置繼續執行
yield return new WaitForSeconds(float n): 程序等待n秒後從當前位置繼續執行
yield return WWW: 等待一個網絡請求完成後從當前位置繼續執行
yield return StartCoroutine(): 等待一個協程執行完成後從當前位置繼續執行
yield new WaitForEndOfFrame(): 在所有的渲染以及GUI程序執行完成後從當前位置繼續執行
yield new WaitForFixedUpdate(): 所有腳本中的FixedUpdate()函數都被執行後從當前位置繼續執行
yield break:協程執行條件不滿足,即不會從當前的位置繼續執行協程,將回到函數繼續執行。

協程的一些注意地方:

  1. 多個協程可以同時運行,它們會根據各自的啓動順序來更新;
  2. 協程可以嵌套任意多層;
  3. 如果你想讓多個腳本訪問一個協程,那麼你可以定義靜態的協程;
  4. 如果你的程序需要進行大量的計算,那麼可以考慮在一個隨時間進行的協程中處理它們;
  5. IEnumerator類型的方法不能帶ref或者out型的參數,但可以帶被傳遞的引用;
  6. 目前在Unity中不能檢測作用於對象的協程數量以及具體是哪些協程作用在對象上。

協程簡單實例

  1. 運動到某一位置
    對於下面這個簡單腳本組件,我們可以在Inspector面板中給targetPosition和moveSpeed變量賦值,程序運行的時候,該對象就會在協程的作用下,以我們給定的速度運動到給定的位置。
usingUnityEngine;  
Using System.Collections;  
   
Public class MoveExample : MonoBehaviour  
{  
    public Vector3 targetPosition;  
    public float moveSpeed;  
   
    Void Start()  
    {  
        StartCoroutine(MoveToPosition(targetPosition));  
    }  
   
    IEnumerator MoveToPosition(Vector3 target)  
    {  
        while(transform.position != target)  
        {  
            transform.position = Vector3.MoveTowards(transform.position, target, moveSpeed * Time.deltaTime);  
            Yield return 0;  
        }  
    }  
}  
  1. 按指定路徑前進
    我們可以讓運動到某一位置的程序做更多,不僅僅是一個指定位置,我們還可以通過數組來給它賦值更多的位置,通過MoveToPosition() ,我們可以讓它在這些點之間持續運動。
Using UnityEngine;  
Using System.Collections;  
   
Public class MoveExample : MonoBehaviour  
{  
    public Vector3[] path;  
    public float moveSpeed;  
   
    Void Start()  
    {  
        StartCoroutine(MoveOnPath(true));  
    }  
   
    IEnumerator MoveOnPath(bool loop)  
    {  
        do  
        {  
            foreach(var point in path)  
                Yield return StartCoroutine(MoveToPosition(point));  
        }  
        while(loop);  
    }  
   
    IEnumerator MoveToPosition(Vector3 target)  
    {  
        while(transform.position != target)  
        {  
            transform.position = Vector3.MoveTowards(transform.position, target, moveSpeed * Time.deltaTime);  
            Yield return 0;  
        }  
    }  
}  

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章