如何理解这个Unity协程?
using UnityEngine;
using System.Collections;
public class CoroutineExample : MonoBehaviour
{
IEnumerator Start ()
{
print ("Starting " + Time.time);
yield return StartCoroutine (WaitAndPrint ());
print ("Done " + Time.time);
}
IEnumerator WaitAndPrint ()
{
yield return new WaitForSeconds (5f);
print ("WaitAndPrint " + Time.time);
}
}
结果是
Starting 0
WaitAndPrint 5.010554
Done 5.010554
我有两个问题?
首先,如何理解函数Start()的返回值。 我曾经看到Start()的返回值是void。 在我看来,Start()只能通过Unity执行一次(一帧),但是yield返回似乎使Start()函数在两帧中执行;
其次,我也对结果感到困惑。 我认为结果应该是
Starting 0
Done 5.010554
WaitAndPrint 5.010554
因为StartCoroutine()启动WaitAndPrint()函数。 在函数WaitAndPrint()中,yield return使此函数在此框架中暂停并返回到Start()。 然后开始()继续并打印“完成xxxxx”。 5秒后,WaitAndPrint()继续并打印“WaitAndPrint xxxxx”。
我错在哪里?
当你调用yield return
,控制权由Unity采用。
当你启动一个Coroutine
Unity会把该方法返回的IEnumerator
并在返回的IEnumerator
上调用MoveNext。
基于对象的类型和对象中的值,Unity将决定要做什么。
在Start
方法的情况下, yield
语句返回另一个IEnumerator
所以Unity不会在Start
返回的对象上调用MoveNext
,直到第二个IEnumerator
完成。
在WaitAndPrint
,第一个MoveNext
返回一个WaitForSeconds
对象,基于Unity决定它将不会调用MoveNext
直到5秒过去。 5秒钟后,它再次调用MoveNext
并执行其余的方法,这就是这一行
print ("WaitAndPrint" + Time.time);
由于yield return StartCoroutine (WaitAndPrint ());
的IEnumerator
返回yield return StartCoroutine (WaitAndPrint ());
达到了它的结尾,它将在由Start
返回的IEnumerator
上调用MoveNext
,这将继续执行Start
:
print ("Done " + Time.time);
希望这是清楚的:)
以下是我理解这个结果的方式:
Start()函数由Unity调用一次并打印“Started”。
接下来的行会做两件事:
yield return StartCoroutine (WaitAndPrint ());
WaitAndPrint()协程将完成它的工作:
然后,Start()协程将恢复并打印“完成”+时间。
这就是为什么
print ("WaitAndPrint" + Time.time);
之前打印:
print ("Done " + Time.time);
此外,你应该编辑你的文章,它会错过第一个结果中的空格:
WaitAndPrint5.010554
应该
WaitAndPrint 5.010554
对不起,如果它不清楚,这是我第一次回答StackOverflow,希望它有帮助!
IEnumerators
是迭代器块,它们不一定在1帧内执行,当你放置一个yield return
,你基本上是在告诉它遍历多个帧。
在迭代器方法中达到yield return语句时,将返回expression,并保留代码中的当前位置。