我目前正在Unity的环境中尝试理解IEnumerator & Coroutine,对“yield return null”的执行不是很有信心。目前我相信它基本上是暂停并等待下一帧,在下一帧中它会返回并再次执行while语句。
如果我省略了“yield return null”,对象似乎会立即移动到它的目的地,或者可能“跳过很多帧”,所以我想我的问题是这个while循环中的“yield return null”函数是如何实现的,为什么有必要有它。
void Start () {
StartCoroutine(Move());
}
IEnumerator Move(){
while (a > 0.5f){
... (moves object up/down)
yield return null; // <---------
}
yield return new WaitForSeconds(0.5f);
.... (moves object up/down)
StartCoroutine(Move());
}
3条答案
按热度按时间mkshixfv1#
程序会开始循环,如果你没有yield,它只是在同一帧内运行所有迭代;如果你有数百万次迭代,那么它很可能会阻塞你的程序,直到所有迭代完成,然后继续。
当创建一个协程时,Unity将它附加到一个MonoBehaviour对象。它将首先运行StartCoroutine的调用,直到一个yield被命中。然后它将从协程返回,并基于yield将它放置到堆栈上。如果你产生null,那么它将在下一帧再次运行。有许多不同的YieldInstruction可以从协程返回。你可以阅读更多关于他们here and through the related links.
一旦一个协程已经让步,主线程继续运行。在下一帧,Unity将找到堆叠的协程,并从它们在让步时停止的地方调用它们。如果你的协程从未超出作用域,那么你基本上创建了一个更新方法。
协程的目的是执行可以跨越一段时间而不阻塞程序的操作。
重要事实:这不是多线程。
jvlzgdj92#
你是对的。
yield return null
将等待下一帧,然后继续执行。在你的例子中,它将检查你的while循环下一帧的条件。“为什么这是必要的”可能是因为你想让对象在每一帧都通过输入移动。如果没有
yield return null
,它只会在一帧中通过while循环执行。更重要的是:看起来你想每一帧都
Update
并调整psoition。你可以很容易地使用Update ()
。这个函数将被Unity在活动脚本的每一帧调用。piok6c0g3#
你必须在ienumorator中返回一些东西,它不是一个void方法.你也可以
yield return new WaitforSecond(1f)
来等待更长的时间