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>  

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值