理解:協程不是線程,也不是異步執行(知道就行)。
1.協程和MonoBehaviour的Update函數一樣,也是在MainThread中執行的(一定得明白這句話意思)。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | void Start () { StartCoroutine(HelloCoroutine()); } void Update () { Debug.Log( "Update..." ); } void LateUpdate() { Debug.Log( "LateUpdate..." ); } IEnumerator HelloCoroutine() { while ( true ) { Debug.Log( "Coroutine..." ); yield return null ; } } |
1 |
對比以上代碼和兩張截圖。這樣寫協程,好像是高級一點的Update寫法。至少應該可以看出,這種寫法的協程可以完成update的功能。
2.與update不一樣的地方。
1 2 3 4 5 6 7 8 9 10 11 12 | IEnumerator Count() { int seconds = 0; while ( true ) { for ( float timer = 0; timer < 2; timer += Time.deltaTime) yield return 0; seconds++; Debug.Log(seconds + " seconds have passed since the Coroutine started." ); } }<br> |
3.yield
yiled return null 等同於 yield return 0
我這邊的理解是,停止正在執行的方法,並從下一幀開始執行(一般是0.02秒,與Update的每一幀是一樣的,具體看Unity設置的timer)。
4.協程是可以傳遞參數的。
5.協程還可以嵌套協程。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | IEnumerator HelloCoroutinue() { Debug.Log( "Start----" ); yield return StartCoroutine(Wait(0.2f)); // yield return new WaitForSeconds(0.2f);最終達到的效果是一樣的。 Debug.Log( "End----" ); } IEnumerator Wait( float s) { for ( float timer =0;timer< s;timer+=Time.deltaTime) { Debug.Log( "當前 timer" + timer.ToString()); yield return 0; // yield return null; } Debug.Log( "Wait....." ); } |
看截圖中畫線的時間差,再次驗證了與Update好像。暫停的時間都是一樣的。
可以看到暫停了當前的方法去執行yield return後的方法。
補充注意:
a.多個協程可以同時運行,它們會根據各自的啓動順序來更新;
b.如果你想讓多個腳本訪問一個協程,可以定義爲靜態的協程;