怎么理解这个Unity Coroutine呢?
How to understand this Unity Coroutine?
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()的return值。我曾经看到 Start() 的 return 值是无效的。在我看来,Start() 仅由 Unity 执行一次(一帧),但 yield return 似乎使 Start() 函数在两帧中执行;
其次,我也对结果感到困惑。我认为结果应该是
Starting 0
Done 5.010554
WaitAndPrint 5.010554
因为StartCoroutine() 启动了函数WaitAndPrint()。在函数 WaitAndPrint() 中,yield return 使该函数在此帧暂停并 return 到 Start()。然后 Start() 继续进行并打印 "Done xxxxx"。 5 秒后,WaitAndPrint() 恢复并
打印 "WaitAndPrint xxxxx"。
我哪里错了?
IEnumerators
是迭代器块,它们不一定执行 1 帧,当您放置 yield return
时,您实际上是在告诉它迭代多个帧。
When a yield return statement is reached in the iterator method,
expression is returned, and the current location in code is retained.
以下是我对这个结果的理解:
Unity 调用 Start() 函数一次并打印 "Started".
然后下一行做了两件事:
yield return StartCoroutine (WaitAndPrint ());
- 它启动 WaitAndPrint() 协程
- 它会等待它结束,然后再继续 Start() 协程。
WaitAndPrint() 协程将完成它的任务:
- 等待 5 秒
- 打印"WaitAndPrint"+时间
然后 Start() 协程将恢复并打印 "Done" + 时间。
这就是为什么
print ("WaitAndPrint" + Time.time);
打印在 :
之前
print ("Done " + Time.time);
此外,您应该编辑 post,它在第一个结果中遗漏了 space:
WaitAndPrint5.010554
应该是
WaitAndPrint 5.010554
抱歉,如果不清楚,这是我第一次在 Whosebug 上回答,希望对您有所帮助!
当您调用 yield return
时,控制权由 Unity 接管。
当您启动 Coroutine
Unity 时,Unity 将采用 IEnumerator
return 方法,并将在 IEnumerator
[=50] 上调用 MoveNext =]ed.
根据对象的类型和对象中的值,Unity 将决定要做什么。
在你的情况下,在 Start
方法中 yield
语句 return 另一个 IEnumerator
所以 Unity 不会在 [=16= 上调用 MoveNext
] returned 对象直到第二个 IEnumerator
完成。
在 WaitAndPrint
中,第一个 MoveNext
return 是一个 WaitForSeconds
对象,基于此,Unity 决定它 不会 在 5 秒后调用 MoveNext
。 5 秒后它再次调用 MoveNext
并执行方法的其余部分,就是这一行
print ("WaitAndPrint" + Time.time);
当 yield return StartCoroutine (WaitAndPrint ());
编辑的 IEnumerator
return 结束时,它将在 return 编辑的 IEnumerator
上调用 MoveNext
通过 Start
,这将依次执行 Start
:
的剩余部分
print ("Done " + Time.time);
希望这已经够清楚了:)
您可以 "nearly" 始终使用 Invoke 方法而不是 IEnumerators。尝试使用那个,你的生活会更轻松 :)
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()的return值。我曾经看到 Start() 的 return 值是无效的。在我看来,Start() 仅由 Unity 执行一次(一帧),但 yield return 似乎使 Start() 函数在两帧中执行;
其次,我也对结果感到困惑。我认为结果应该是
Starting 0
Done 5.010554
WaitAndPrint 5.010554
因为StartCoroutine() 启动了函数WaitAndPrint()。在函数 WaitAndPrint() 中,yield return 使该函数在此帧暂停并 return 到 Start()。然后 Start() 继续进行并打印 "Done xxxxx"。 5 秒后,WaitAndPrint() 恢复并 打印 "WaitAndPrint xxxxx"。
我哪里错了?
IEnumerators
是迭代器块,它们不一定执行 1 帧,当您放置 yield return
时,您实际上是在告诉它迭代多个帧。
When a yield return statement is reached in the iterator method, expression is returned, and the current location in code is retained.
以下是我对这个结果的理解:
Unity 调用 Start() 函数一次并打印 "Started".
然后下一行做了两件事:
yield return StartCoroutine (WaitAndPrint ());
- 它启动 WaitAndPrint() 协程
- 它会等待它结束,然后再继续 Start() 协程。
WaitAndPrint() 协程将完成它的任务:
- 等待 5 秒
- 打印"WaitAndPrint"+时间
然后 Start() 协程将恢复并打印 "Done" + 时间。
这就是为什么
print ("WaitAndPrint" + Time.time);
打印在 :
之前print ("Done " + Time.time);
此外,您应该编辑 post,它在第一个结果中遗漏了 space:
WaitAndPrint5.010554
应该是
WaitAndPrint 5.010554
抱歉,如果不清楚,这是我第一次在 Whosebug 上回答,希望对您有所帮助!
当您调用 yield return
时,控制权由 Unity 接管。
当您启动 Coroutine
Unity 时,Unity 将采用 IEnumerator
return 方法,并将在 IEnumerator
[=50] 上调用 MoveNext =]ed.
根据对象的类型和对象中的值,Unity 将决定要做什么。
在你的情况下,在 Start
方法中 yield
语句 return 另一个 IEnumerator
所以 Unity 不会在 [=16= 上调用 MoveNext
] returned 对象直到第二个 IEnumerator
完成。
在 WaitAndPrint
中,第一个 MoveNext
return 是一个 WaitForSeconds
对象,基于此,Unity 决定它 不会 在 5 秒后调用 MoveNext
。 5 秒后它再次调用 MoveNext
并执行方法的其余部分,就是这一行
print ("WaitAndPrint" + Time.time);
当 yield return StartCoroutine (WaitAndPrint ());
编辑的 IEnumerator
return 结束时,它将在 return 编辑的 IEnumerator
上调用 MoveNext
通过 Start
,这将依次执行 Start
:
print ("Done " + Time.time);
希望这已经够清楚了:)
您可以 "nearly" 始终使用 Invoke 方法而不是 IEnumerators。尝试使用那个,你的生活会更轻松 :)