一。什麼是協同程序編程
協同程序,即在主程序運行時同時開啓另外一段邏輯處理,來協同當前程序的執行。換句話說,開啓協同程序就是開啓一個線程。性能
二。協同程序的開啓與終止url
在Unity3D中,使用MonoBehaviour.StartCoroutine方法便可開啓一個協同程序,也就是說該方法必須在MonoBehaviour或繼承於MonoBehaviour的類中調用。spa
在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中,這樣咱們在編程時就能夠方便的調用指定腳本 中的協同程序,而不是沒法去管理,特別是對於只根據方法名來判斷線程的方式在多人開發中很容易出錯,這樣的設計保證了對象、腳本的條理化管理,並防止了重 名。3d
三。協同程序的輸入、輸出類型對象
協同程序的返回類型爲Coroutine類型。在Unity3D中,Coroutine類繼承於YieldInstruction,因此,協同程序的返回類型只能爲null、等待的幀數(frame)以及等待的時間。繼承
協同程序的參數不能指定ref、out參數。可是,咱們在使用WWW類時會常用到協同程序,因爲在協同程序中不能傳遞參數地址(引用),也不能輸出對 象,這使得每下載一個WWW對象都得重寫一個協同程序,解決這個問題的方法是創建一個基於WWW的類,並實現一個下載方法。以下:ip
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;
}
}
}