当在Unity中编写协程(尤其是协程套无限循环)时,常常会用到yield关键字来控制协程的执行流程避免程序假死。以下是常见做法:
yield return null
当使用yield return null时,协程会在下一帧继续执行。这意味着协程将暂停一帧,然后在下一帧继续执行。使用yield return null可以在每一帧之间进行操作,比如更新游戏对象的位置、旋转或者其他计算。
IEnumerator MyCoroutine()
{
while (true)
{
// Do something
yield return null;
}
}
yield return new WaitForEndOfFrame()
与yield return null不同,yield return new WaitForEndOfFrame()会等待当前帧的渲染完成后再继续执行。这意味着协程会在当前帧的末尾执行,通常用于在所有渲染操作完成后再执行一些操作。
IEnumerator MyCoroutine()
{
while (true)
{
// Do something
yield return new WaitForEndOfFrame();
}
}
区别总结
- yield return null会在下一帧继续执行,用于在每一帧之间进行操作。
- yield return new WaitForEndOfFrame()会等待当前帧渲染完成后再执行,用于在渲染操作完成后执行特定操作。
有趣现象
正如上文总结,一个在下一帧继续执行,一个是等渲染结束然后继续执行。如果读者还是没什么感受的话,可以尝试写两个协程分别使用上文所提到的两种等待方式(最好留一个log输出),然后在编辑器执行。
运行过程中,尝试来回切换Scene和Game视图,看看log输出有什么变化。注意不要把这两个窗口独立出来,否则俩视图永远都是活动状态。
理论上你应该会发现当你切换到Scene视图时,你的WaitForEndOfFrame会卡住,永远不会启动新一轮循环;而使用null的部分却正常进行新一轮循环。
所以如果你遇到切后台或者编辑器切视图后协程暂停的表现,多半是WaitForEndOfFrame卡住了。如果代码和渲染有很强关联性,那么请继续用WaitForEndOfFrame,否则使用null。