Unity3D協同程序(Coroutine)

  

摘要下:

1.html

coroutine, 中文翻譯「協程」。這個概念可能有點冷門,不過百度之,說是一種很古老的編程模型了,之前的操做系統裏進程調度裏用到過,如今操做系統的進程調度都是根據 時間片和優先級來進行輪換,之前是要程序本身來釋放cpu的控制權,一直不釋放一直也就佔用着cpu,這種要求程序本身來進行調度的編程模型應該就叫「協 程」了。程序員

協程和線程差很少,線程的調度是由操做系統完成的,協程把這項任務交給了程序員本身實現,固然也就能夠提升靈活性,另外協程的開銷比線程要小,在程序裏能夠開更多的協程。編程

一些語言裏自帶了對coroutine的實現,好比lua。c裏面雖然沒有coroutine,不過windows下提供了一種叫fiber的機制,叫作「纖程」,算是一種輕量級線程。windows

 

2.函數

一。什麼是協同程序post

       協同程序,即在主程序運行時同時開啓另外一段邏輯處理,來協同當前程序的執行。換句話說,開啓協同程序就是開啓一個線程。性能

 

二。協同程序的開啓與終止this

       在Unity3D中,使用MonoBehaviour.StartCoroutine方法便可開啓一個協同程序,也就是說該方法必須在MonoBehaviour或繼承於MonoBehaviour的類中調用。lua

       在Unity3D中,使用StartCoroutine(string methodName)和StartCoroutine(IEnumerator routine)均可以開啓一個線程。區別在於使用字符串做爲參數能夠開啓線程並在線程結束前終止線程,相反使用IEnumerator  做爲參數只能等待線程的結束而不能隨時終止(除非使用StopAllCoroutines()方法);另外使用字符串做爲參數時,開啓線程時最多隻能傳遞 一個參數,而且性能消耗會更大一點,而使用IEnumerator 做爲參數則沒有這個限制。spa

        在Unity3D中,使用StopCoroutine(string methodName)來終止一個協同程序,使用StopAllCoroutines()來終止全部能夠終止的協同程序,但這兩個方法都只能終止該 MonoBehaviour中的協同程序。

        還有一種方法能夠終止協同程序,即將協同程序所在gameobject的active屬性設置爲false,當再次設置active爲ture時,協同程 序並不會再開啓;如是將協同程序所在腳本的enabled設置爲false則不會生效。這是由於協同程序被開啓後做爲一個線程在運行,而  MonoBehaviour也是一個線程,他們成爲互不干擾的模塊,除非代碼中用調用,他們共同做用於同一個對象,只有當對象不可見才能同時終止這兩個線 程。然而,爲了管理咱們額外開啓的線程,Unity3D將協同程序的調用放在了MonoBehaviour中,這樣咱們在編程時就能夠方便的調用指定腳本 中的協同程序,而不是沒法去管理,特別是對於只根據方法名來判斷線程的方式在多人開發中很容易出錯,這樣的設計保證了對象、腳本的條理化管理,並防止了重 名。

個人一些粗淺小結:

1.Coroutines顧名思議是用來協助主要進程的,在Unity中感受就是一個可動態添加和移除的Update()函數。它的調用在全部Update函數以後。

Unity原文:

  • If you start a coroutine in LateUpdate it will also be called after LateUpdate just before rendering.
  • Coroutines are executed after all Update functions.

2.yield就像是一個紅綠燈,在知足緊跟在它後面的條件以前,這個協程會掛起,把執行權交給調用它的父函數,知足條件時就能夠執行yield下面的代碼。

Unity原文:

Normal coroutine updates are run after the Update function returns. A coroutine is function that can suspend its execution (yield) until the given given YieldInstruction finishes. Different uses of Coroutines:

  • yield;等待 all Update functions 已被call過,The coroutine will continue on the next frame.
  • yield WaitForSeconds(2);Continue after a specified time delay, after all Update functions have been called for the frame
  • yield WaitForFixedUpdate();Continue after all FixedUpdate has been called on all scripts
  • yield WWWContinue after a WWW download has completed.
  • yield StartCoroutine(MyFunc); Chains the coroutine, and will wait for the MyFunc coroutine to complete first.

 

協同的用法

Yield中斷:(有中斷就表明程序停在該處,等待yield後的時間結束再繼續執行後面的語句。)

http://unity3d.com/support/documentation/ScriptReference/index.Coroutines_26_Yield.html

http://game.ceeger.com/Script/Overview/Overview.Coroutines_Yield.html

注意:

  • 在unity C#中yield(中斷)語句必需要在IEnumerator類型裏

  • C#方法,方法的返回類型爲IEnumerator,返回值如(eg: yield return new WaitForSeconds(2);  或者 yield return null;)。

  • yields不能夠在Update或者FixedUpdate裏使用。


示例:
這個例子將執行Do,可是do以後的print會馬上執行:

 

 1 using UnityEngine;
 2 using System.Collections;
 3 
 4 public class example : MonoBehaviour {
 5 public static IEnumerator Do() {
 6   print("Do now");
 7   yield return new WaitForSeconds(2);
 8   print("Do 2 seconds later");
 9 }
10 void Awake() {
11   Do();    //執行DO,可是do後的語句繼續執行
12   print("This is printed immediately");
13 }

這個例子將執行Do,並等待,直到Do完成再執行其餘語句:

 1 using UnityEngine;
 2 using System.Collections;
 3 
 4 public class example : MonoBehaviour {
 5     IEnumerator Do() {
 6         print("Do now");
 7         yield return new WaitForSeconds(2);
 8         print("Do 2 seconds later");
 9     }
10     IEnumerator Awake() {
11         yield return StartCoroutine("Do");    //Yield StartCoroutine就表明中斷式的協同工做
12         print("Also after 2 seconds");
13         print("This is after the Do coroutine has finished execution");
14     }
15 }

Coroutine協同:(爲何要有Coroutine的概念? 由於有中斷的存在,試想一個程序都靠Yield來暫停的話,如何作到一個事件暫停的過程當中,暫停過程當中繼續執行後面的程序? 那麼就要靠Coroutine來實現。)

http://unity3d.com/support/documentation/ScriptReference/MonoBehaviour.StartCoroutine.html?from=YieldInstruction 

http://game.ceeger.com/Script/MonoBehaviour/MonoBehaviour.StartCoroutine.html

  • 能夠在UPdate或者FixedUpdate裏使用coroutine
  • 這裏有兩種:StartCoroutine(協同工做) 和 yield return StartCoroutine(中斷式的協同工做)
  • 有yield的表明先執行完本語句(無論多長時間),或者執行完本yield方法調用,才執行後續語句。例如StartCoroutine(WaitAndPrint(2.0F)),繼續執行StartCoroutine後面的語句,
  • 沒有yield的表明繼續順序執行。例如:yield return StartCoroutine(WaitAndPrint(2.0F)),表明StartCoroutine(WaitAndPrint(2.0F))函數裏等待所有執行完,再執行StartCoroutine後面的語句

 StartCoroutine的例子:

 1 // In this example we show how to invoke a coroutine and continue executing
 2 // the function in parallel.
 3 // 此例演示如何調用協同程序和它的執行
 4 function Start() {
 5     // - After 0 seconds, prints "Starting 0.0"
 6     // - After 0 seconds, prints "Before WaitAndPrint Finishes 0.0"
 7     // - After 2 seconds, prints "WaitAndPrint 2.0"
 8     // 先打印"Starting 0.0"和"Before WaitAndPrint Finishes 0.0"兩句,2秒後打印"WaitAndPrint 2.0"
 9     print ("Starting " + Time.time );
10     // Start function WaitAndPrint as a coroutine. And continue execution while it is running
11     // this is the same as WaintAndPrint(2.0) as the compiler does it for you automatically
12     // 協同程序WaitAndPrint在Start函數內執行,能夠視同於它與Start函數同步執行.
13     StartCoroutine(WaitAndPrint(2.0)); 
14     print ("Before WaitAndPrint Finishes " + Time.time );
15 }
16 
17 function WaitAndPrint (waitTime : float) {
18     // suspend execution for waitTime seconds
19     // 暫停執行waitTime秒
20     yield WaitForSeconds (waitTime);
21     print ("WaitAndPrint "+ Time.time );
22 }

C# 版本

 1 using UnityEngine;
 2 using System.Collections;
 3 
 4 public class example : MonoBehaviour {
 5     void Start() {
 6     print("Starting " + Time.time);
 7         StartCoroutine(WaitAndPrint(2.0F));
 8         print("Before WaitAndPrint Finishes " + Time.time);
 9     }
10     IEnumerator WaitAndPrint(float waitTime) {
11         yield return new WaitForSeconds(waitTime);
12         print("WaitAndPrint " + Time.time);
13     }
14 }

yield return StartCoroutine的例子:

 1 // In this example we show how to invoke a coroutine and wait until it 
 2 // is completed
 3 // 在這個例子中咱們演示如何調用協同程序並直到它執行完成.
 4 function Start() {
 5     // - After 0 seconds, prints "Starting 0.0"
 6     // - After 2 seconds, prints "WaitAndPrint 2.0"
 7     // - After 2 seconds, prints "Done 2.0"
 8     // 0秒時打印"Starting 0.0",2秒後打印"WaitAndPrint 2.0"和"Done 2.0"
 9     print ("Starting " + Time.time );
10     // Start function WaitAndPrint as a coroutine. And wait until it is completed.
11     // the same as yield WaitAndPrint(2.0);
12     // 運行WaitAndPrint直到完成
13     yield StartCoroutine(WaitAndPrint(2.0));
14     print ("Done " + Time.time );
15 }
16 
17 function WaitAndPrint (waitTime : float) {
18     // suspend execution for waitTime seconds
19     // 等待waitTime秒
20     yield WaitForSeconds (waitTime);
21     print ("WaitAndPrint "+ Time.time );
22 }

C#版本

 1 using UnityEngine;
 2 using System.Collections;
 3 
 4 public class example : MonoBehaviour {
 5     IEnumerator Start() {
 6         print("Starting " + Time.time);
 7         yield return StartCoroutine(WaitAndPrint(2.0F));
 8         print("Done " + Time.time);
 9     }
10     IEnumerator WaitAndPrint(float waitTime) {
11         yield return new WaitForSeconds(waitTime);
12         print("WaitAndPrint " + Time.time);
13     }
14 }
相關文章
相關標籤/搜索