1. 程式人生 > >Unity3D協同程式(Coroutine)

Unity3D協同程式(Coroutine)

摘要下:

1.

coroutine, 中文翻譯“協程”。這個概念可能有點冷門,不過百度之,說是一種很古老的程式設計模型了,以前的作業系統裡程序排程裡用到過,現在作業系統的程序排程都是根據 時間片和優先順序來進行輪換,以前是要程式自己來釋放cpu的控制權,一直不釋放一直也就佔用著cpu,這種要求程式自己來進行排程的程式設計模型應該就叫“協 程”了。

協程和執行緒差不多,執行緒的排程是由作業系統完成的,協程把這項任務交給了程式設計師自己實現,當然也就可以提高靈活性,另外協程的開銷比執行緒要小,在程式裡可以開更多的協程。

一些語言裡自帶了對coroutine的實現,比如lua。c裡面雖然沒有coroutine,不過windows下提供了一種叫fiber的機制,叫做“纖程”,算是一種輕量級執行緒。

2.

一。什麼是協同程式

       協同程式,即在主程式執行時同時開啟另一段邏輯處理,來協同當前程式的執行。換句話說,開啟協同程式就是開啟一個執行緒

二。協同程式的開啟與終止

       在Unity3D中,使用MonoBehaviour.StartCoroutine方法即可開啟一個協同程式,也就是說該方法必須在MonoBehaviour或繼承於MonoBehaviour的類中呼叫。

       在Unity3D中,使用StartCoroutine(string methodName)和StartCoroutine(IEnumerator routine)都可以開啟一個執行緒。區別在於使用字串作為引數可以開啟執行緒並在執行緒結束前終止執行緒,相反使用IEnumerator 作為引數只能等待執行緒的結束而不能隨時終止(除非使用StopAllCoroutines()方法)

;另外使用字串作為引數時,開啟執行緒時最多隻能傳遞 一個引數,並且效能消耗會更大一點,而使用IEnumerator 作為引數則沒有這個限制。

        在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.