协同程序
首先,必须要了解的是,游戏引擎(例如 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
}
}
}