Unity3D之協程(Coroutines & Yield ) 函數
寫遊戲代碼,每每最終須要代碼爲連續的事件.結果會像這樣:
[它能夠實現將一段程序延遲執行或者將其各個部分分佈在一個時間段內連續執行。]
spa
private int state = 0;
void Update()
{
if (state == 0)
{
//作步驟0
state = 1;
return;
}
if (state == 1)
{
// 作步驟1
state = 2;
return;
}
// ...
}
每每使用yield語句更爲方便.yield語句是一個特殊的返回類型,它確保函數從yield語句的下一行繼續執行.
.net
while(true) {
// 作步驟0
yield return 0;
// 等待一幀
// 作步驟1
yield return 2;
// 等待兩幀
// ...
}
你也能夠傳遞時間值到yield語句,Update函數會在yield結束後執行下一語句.
線程
// do something
yield return WaitForSeconds (5.0);
//等待5秒
// do something more...
你能夠入棧並鏈接協程.
這個例子將執行Do,可是do函數以後的print指令會馬上執行.
code
Do ();
Console.WriteLine("This is printed immediately");
IEnumerator Do ()
{
Console.WriteLine("Do now");
yield return new WaitForSeconds (2);
Console.WriteLine("Do 2 seconds later");
}
這個例子將執行Do,並等待,直到Do完成再執行其餘語句.【注:這裏的等待是把線程時間交給其餘任務,而不是阻塞式等待】
協程
// 啓動協程
yield return StartCoroutine("Do");
Console.WriteLine("Also after 2 seconds");
Console.WriteLine ("這個print將在Do協程執行完之後顯示。");
IEnumerator Do ()
{
Console.WriteLine("Do now");
yield return new WaitForSeconds (2);
Console.WriteLine("Do 2 seconds later");
}
任何事件處理程序均可以是協同程序 。
注意你不能在Update或FixedUpdate函數內使用yield,可是你能使用 StartCoroutine 開始一個函數.
查看 YieldInstruction , WaitForSeconds , WaitForFixedUpdate , Coroutine and MonoBehaviour.StartCoroutine 能夠得到更多使用yield的信息.
yield return能夠看作是一種特殊的return,會返回到父類繼續執行,可是yield return後面的類型或方法會有一個執行條件,當條件知足時會回調包含yield的子函數,例以下面代碼
例1:
blog
void Start () {
print("Starting:" + Time.time);
StartCoroutine(WaitAnPrint(2.0F));
print("Before WaiAndPrint:" + Time.time);
}
IEnumerator WaitAndPrint(float waitTime)
{
yield return new WaitForSeconds(waitTime);
print("WaitAndPrint:" + Time.time);
}
在執行yield return new WaitForSeconds(waitTime)時暫停的條件沒有知足,故返回到start函數中繼續執行,直到知足條件後再回調WaitAndPrint,因此輸出爲:
Starting:0
Before WaiAndPrint:0
WaitAndPrint:2.12291
例2:
遊戲
IEnumerator Start()
{
print("starting:" + Time.time);
yield return StartCoroutine(WaitAndPrint(2.0F));
print("done:" + Time.time);
}
IEnumerator WaitAndPrint(float waitTime)
{
yield return new WaitForSeconds(waitTime);
print("WaitAndPrint:" + Time.time);
}
由於start爲頂級函數,因此會阻塞在這裏,直到StartCoroutine(WaitAndPrint(2.0F))執行完畢,輸出爲:
starting:0
WaitAndPrint:2.00315
done:2.00315
事件