Unity3D之協程(Coroutines & Yield )

寫遊戲代碼,每每最終須要代碼爲連續的事件.結果會像這樣:
[它能夠實現將一段程序延遲執行或者將其各個部分分佈在一個時間段內連續執行。]

[csharp]  view plain copy print ?
 
  1. <span style="font-size:18px;">private int state = 0;  
  2. void Update()  
  3. {  
  4.         if (state == 0)   
  5.         {  
  6.                 //作步驟0  
  7.                 state = 1;  
  8.                 return;  
  9.         }  
  10.         if (state == 1)   
  11.         {  
  12.                 // 作步驟1  
  13.                 state = 2;  
  14.                 return;  
  15.         }  
  16.         // ...  
  17. } </span>  


每每使用yield語句更爲方便.yield語句是一個特殊的返回類型,它確保函數從yield語句的下一行繼續執行.


[csharp]  view plain copy print ?
 
  1. <span style="font-size:18px;">while(true) {  
  2.         // 作步驟0  
  3.         yield return 0;  
  4.          // 等待一幀  
  5.         // 作步驟1  
  6.         yield return 2;  
  7.          // 等待兩幀  
  8.         // ...  
  9. } </span>  


你也能夠傳遞時間值到yield語句,Update函數會在yield結束後執行下一語句.

[csharp]  view plain copy print ?
 
  1. <span style="font-size:18px;">  // do something  
  2.   yield return WaitForSeconds  (5.0);  
  3.   //等待5秒  
  4.   // do something more...  </span>  

你能夠入棧並鏈接協程.


這個例子將執行Do,可是do函數以後的print指令會馬上執行.


[csharp]  view plain copy print ?
 
  1. <span style="font-size:18px;">Do ();  
  2. Console.WriteLine("This is printed immediately");  
  3. IEnumerator  Do ()  
  4. {  
  5.     Console.WriteLine("Do now");  
  6.     yield return new WaitForSeconds  (2);        
  7.     Console.WriteLine("Do 2 seconds later");  
  8. } </span>  


這個例子將執行Do,並等待,直到Do完成再執行其餘語句.【注:這裏的等待是把線程時間交給其餘任務,而不是阻塞式等待】


[csharp]  view plain copy print ?
 
  1. <span style="font-size:18px;">// 啓動協程  
  2. yield return StartCoroutine("Do");  
  3. Console.WriteLine("Also after 2 seconds");  
  4. Console.WriteLine ("這個print將在Do協程執行完之後顯示。");  
  5. IEnumerator  Do ()  
  6. {        
  7. Console.WriteLine("Do now");  
  8. yield return new WaitForSeconds  (2);  
  9. Console.WriteLine("Do 2 seconds later");  
  10. }  
  11. </span>  


任何事件處理程序均可以是協同程序 。


注意你不能在Update或FixedUpdate函數內使用yield,可是你能使用 StartCoroutine  開始一個函數.


查看 YieldInstruction , WaitForSeconds , WaitForFixedUpdate , Coroutine  and MonoBehaviour.StartCoroutine  能夠得到更多使用yield的信息.
yield return能夠看作是一種特殊的return,會返回到父類繼續執行,可是yield return後面的類型或方法會有一個執行條件,當條件知足時會回調包含yield的子函數,例以下面代碼
例1:


[csharp]  view plain copy print ?
 
  1. <span style="font-size:18px;">void Start () {  
  2.   
  3.   
  4.         print("Starting:" + Time.time);  
  5.   
  6.   
  7.         StartCoroutine(WaitAnPrint(2.0F));  
  8.   
  9.   
  10.         print("Before WaiAndPrint:" + Time.time);  
  11.   
  12.   
  13.     }  
  14.   
  15.   
  16. IEnumerator WaitAndPrint(float waitTime)  
  17.   
  18.   
  19.     {  
  20.   
  21.   
  22.         yield return new WaitForSeconds(waitTime);  
  23.   
  24.   
  25.         print("WaitAndPrint:" + Time.time);      
  26.   
  27.   
  28.     }  
  29. </span>  


在執行yield return new WaitForSeconds(waitTime)時暫停的條件沒有知足,故返回到start函數中繼續執行,直到知足條件後再回調WaitAndPrint,因此輸出爲:


Starting:0


Before WaiAndPrint:0


WaitAndPrint:2.12291


例2:


[csharp]  view plain copy print ?
 
  1. <span style="font-size:18px;">IEnumerator Start()  
  2.   
  3.   
  4.     {  
  5.   
  6.   
  7.         print("starting:" + Time.time);  
  8.   
  9.   
  10.         yield return StartCoroutine(WaitAndPrint(2.0F));  
  11.   
  12.   
  13.         print("done:" + Time.time);  
  14.   
  15.   
  16.     }  
  17.   
  18.   
  19. IEnumerator WaitAndPrint(float waitTime)  
  20.   
  21.   
  22.     {  
  23.   
  24.   
  25.         yield return new WaitForSeconds(waitTime);  
  26.   
  27.   
  28.         print("WaitAndPrint:" + Time.time);      
  29.   
  30.   
  31.     }</span>  



由於start爲頂級函數,因此會阻塞在這裏,直到StartCoroutine(WaitAndPrint(2.0F))執行完畢,輸出爲:


starting:0

WaitAndPrint:2.00315

done:2.00315
[csharp]  view plain copy print ?
 
  1. <pre name="code" class="csharp"><pre name="code" class="csharp"><pre name="code" class="csharp"><p></p><pre></pre>  
  2. <pre></pre>  
  3. <pre></pre>  
  4. <pre></pre>  
  5. <pre></pre>  
  6. <pre></pre>  
  7. <pre></pre>  
  8. <pre></pre>  
  9. <pre></pre>  
  10. <pre></pre>  
  11. <pre></pre>  
  12. <pre></pre>  
  13. <pre></pre>  
  14. <pre></pre>  
  15. <pre></pre>  
  16. <pre></pre>  
  17. <pre></pre>  
  18. <pre></pre>  
  19. <pre></pre>  
  20.   
  21. </pre></pre></pre>  
相關文章
相關標籤/搜索