[Unity Engine] Coroutine協程 === ###### tags: `Unity Engine` `C#` `Programming` Keynote --- - Coroutine最常做的是『等待』 - Coroutine並不是多執行緒 - Coroutine只能使用`MonoBehaviour`內的`StartCoroutine`進行呼叫 - 與`MonoBehaviour`的生命週期息息相關 Usage ---  :::info 從上圖可以得知幾種等待方式,並有著呼叫順序,這件事告訴我們,一個`MonoBehaviour`的循環或幀書內可能進行著N次對`Coroutine`的回傳與呼叫 ::: 最常使用的方式 - 在固定的循環或時間點中,做一件事 ```C#= private IEnumerator A() { while (true) { Debug.Log("Do something."); yield null; // 也可以使用其他等待的方式 } } ``` - 在一段時間前或後做一件事 ```C#= private IEnumerator B() { Debug.Log("Do something 1~~."); // Print Do something 1~~. yield return new WaitForSeconds(1.0f); Debug.Log("Do something 2~~."); // Print Do something 2~~. after 1 second } ``` - `yield break`之後的程式不會被執行 ```C#= private IEnumerator C() { Debug.Log("Do something 1~~."); Debug.Log("Do something 2~~."); Debug.Log("Do something 3~~."); yield break; Debug.Log("Do something 4~~."); // This won't be call } ``` ### Nested Coroutine - 執行Coroutine A,然後在Coroutine A當中執行並等待Coroutine B完成 ```C#= void start() { StartCoroutine(A()); } IEnumerator A() { Debug.Log("Start A..."); yield return B(); Debug.Log("Finish A..."); } IEnumerator B() { Debug.Log("Start B..."); yield return new WaitForSeconds(5.0f); Debug.Log("It passed 5 seconds"); Debug.Log("Start B..."); } ```  ### Parallel Coroutine - 執行Coroutine A,同時處理Coroutine B和Coroutine C,並依序等待執行的Coroutine結束 ```C#= void Start() { StartCoroutine(A()); } IEnumerator A() { Debug.Log("Start A..."); var b = StartCoroutine(B()); var c = StartCoroutine(C()); yield return b; yield return c; Debug.Log("Finish A..."); } IEnumerator B() { Debug.Log("Start B..."); yield return new WaitForSeconds(2.5f); Debug.Log("It passed 2.5 seconds"); Debug.Log("Finish B..."); } IEnumerator C() { Debug.Log("Start C..."); yield return new WaitForSeconds(2.5f); Debug.Log("It passed 2.5 seconds"); Debug.Log("Finish C..."); } ```  YieldInstruction ---  `WaitForFixedUpdate`、`WaitForEndFrame`、`WaitForSeconds`,這些都是等待固定時間或是幀數,若要進行資源載入或是操作硬體I/O,無法預期要多少時間的話,請使用**AsyncOperation**衍生類別: - SceneManager.LoadSceneAsync():載入場景 - AssetBundle.LoadAssetAsync():載入 AssetBundle - Resources.LoadAsync():從 Resources 目錄載入各種資源 StartCoroutine & StopCoroutine --- ==待補,此段文字來自Reference 2== > Start() 執行過程中所啟動的兩個 Coroutine ,實際上都要等到第二幀之後才會真正開始運行。這雖然看起來似乎是個不太重要的現象,但**當我們提到 await/async 或是多執行緒時,在哪裡執行就會成為大部分工作都要在主執行緒執行的 Unity 很需要考量的地方。** > 透過讓 yield 回傳 Coroutine 類別物件,Coroutine 就可以去等待另一個 Coroutine 完成,但是這兩個 Coroutine 之間的關係到底是什麼?是**互相隸屬**還是個別**獨立運作**?如果我們將其中一個 Coroutine 用 StopCoroutine() 強制中止時,另外一個會出現什麼反應?是否會發生什麼問題?Unity 在 5.3 之後加入了 CustomYieldInstruction 又會改變些什麼?我們為什麼不建議再讓 yield 用回傳 Coroutine 的方式來等待了?這種種的問題,我們很快回來! Reference --- [Unity Coroutine 使用筆記](https://dev.twsiyuan.com/2017/05/unity-coroutine.html) [Coroutine 在等什麼?了解 Unity 的 YieldInstruction 和 Coroutine 類別](https://medium.com/feis-studio/unity-coroutine-yieldinstruction-8e08fa8b3c9f)
×
Sign in
Email
Password
Forgot password
or
By clicking below, you agree to our
terms of service
.
Sign in via Facebook
Sign in via Twitter
Sign in via GitHub
Sign in via Dropbox
Sign in with Wallet
Wallet (
)
Connect another wallet
New to HackMD?
Sign up