NO IMAGE

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

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

在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中,這樣我們在程式設計時就可以方便的呼叫指定指令碼 中的協同程式,而不是無法去管理,特別是對於只根據方法名來判斷執行緒的方式在多人開發中很容易出錯,這樣的設計保證了物件、指令碼的條理化管理,並防止了重 名。 

三。協同程式的輸入、輸出型別

協同程式的返回型別為Coroutine型別。在Unity3D中,Coroutine類繼承於YieldInstruction,所以,協同程式的返回型別只能為null、等待的幀數(frame)以及等待的時間。
協同程式的引數不能指定ref、out引數。但是,我們在使用WWW類時會經常使用到協同程式,由於在協同程式中不能傳遞引數地址(引用),也不能輸出對 象,這使得每下載一個WWW物件都得重寫一個協同程式,解決這個問題的方法是建立一個基於WWW的類,並實現一個下載方法。如下:

usingUnityEngine;
usingSystem.Collections;

publicclassWWWObject:MonoBehaviour
{
public WWW www;

publicWWWObject(string url)
{
if(GameVar.wwwCache)
www =WWW.LoadFromCacheOrDownload(url,GameVar.version);
else
www =new WWW(url);
}

publicIEnumeratorLoad()
{
Debug.Log(“Start loading : “ www.url);
while(!www.isDone)
{
if(GameVar.gameState ==GameState.Jumping||GameVar.gameState ==GameState.JumpingAsync)
LoadScene.progress =www.progress;

yieldreturn1;
}

if(www.error!=null)
Debug.LogError(“Loading error : “ www.url ”\n” www.error);
else
Debug.Log(“End loading : “ www.url);
}

publicIEnumeratorLoadWithTip(string resourcesName)
{
Debug.Log(“Start loading : “ www.url);
LoadScene.tipStr = “Downloading resources <” resourcesName ”> …”;
while(!www.isDone)
{
if(GameVar.gameState ==GameState.Jumping||GameVar.gameState ==GameState.JumpingAsync)
LoadScene.progress =www.progress;

yieldreturn1;
}

if(www.error!=null)
Debug.LogError(“Loading error : “ www.url ”\n” www.error);
else
Debug.Log(“End loading : “ www.url);
}
}

呼叫:
usingUnityEngine;
usingSystem.Collections;
usingSystem.Collections.Generic;

publicclassLoadResources:MonoBehaviour
{
staticstring url =”http://61.149.211.88/Package/test.unity3d”;
publicstatic WWW www =null;

IEnumeratorStart()
{
if(!GameVar.resourcesLoaded)
{
GameVar.gameState =GameState.Jumping;

WWWObject obj =newWWWObject(url);
www = obj.www;
yieldreturnStartCoroutine(obj.LoadWithTip(“Textures”));

GameVar.resourcesLoaded =true;
GameVar.gameState =GameState.Run;
}
}
}