協同程式
首先,必須要了解的是,遊戲引擎(例如 Unity)在基於框架的範例上工作。
程式碼在每一幀中執行。
這包括 Unity 自己的程式碼和程式碼。
在考慮框架時,重要的是要了解框架何時發生絕對不能保證。它們不會發生在常規節拍上。幀之間的間隙可以是例如 0.02632 然後 0.021167 然後是 0.029778,依此類推。在這個例子中,它們都是約1/50 秒,但它們都是不同的。而且在任何時候,你可能會得到一個花費更長或更短的框架; 並且你的程式碼可以在框架內的任何時間執行。
考慮到這一點,你可能會問:在 Unity 中如何訪問程式碼中的這些幀?
很簡單,你使用 Update()
呼叫,或者使用協程。 (確實 - 它們完全相同:它們允許每幀執行程式碼。)
協程的目的是:
你可以執行一些程式碼,然後停止並等待,直到將來的某個框架。
你可以等到下一幀,你可以等待多個幀,或者你可以在將來等待幾秒鐘的大致時間。
例如,你可以等待大約一秒鐘,這意味著它將等待大約一秒鐘,然後將程式碼放在大約一秒鐘的某個幀中。 (事實上,在該框架內,程式碼可以隨時執行。)重複:它不會是一秒鐘。準確的計時在遊戲引擎中毫無意義。
在協程內:
要等一幀:
// do something
yield return null; // wait until next frame
// do something
等待三幀:
// do something
yield return null; // wait until three frames from now
yield return null;
yield return null;
// do something
等待大約半秒鐘:
// do something
yield return new WaitForSeconds (0.5f); // wait for a frame in about .5 seconds
// do something
每一幀做一些事情:
while (true)
{
// do something
yield return null; // wait until the next frame
}
這個例子與簡單地在 Unity 的更新呼叫中放置一些內容完全相同:執行某些操作的程式碼每幀執行一次。
例
將 Ticker 附加到 GameObject
。當該遊戲物件處於活動狀態時,勾選將會執行。請注意,當遊戲物件變為非活動狀態時,指令碼會小心地停止協程; 這通常是正確設計協同程式使用的一個重要方面。
using UnityEngine;
using System.Collections;
public class Ticker:MonoBehaviour {
void OnEnable()
{
StartCoroutine(TickEverySecond());
}
void OnDisable()
{
StopAllCoroutines();
}
IEnumerator TickEverySecond()
{
var wait = new WaitForSeconds(1f); // REMEMBER: IT IS ONLY APPROXIMATE
while(true)
{
Debug.Log("Tick");
yield return wait; // wait for a frame, about 1 second from now
}
}
}