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
事件