【译】定制协程
原文作者未做版权声明,视为共享知识产权进入公共领域,自动获得授权
http://blogs.unity3d.com/2015/12/01/custom-coroutines/
在Unity 5.3发布日志里面,有很多闪亮的新功能,其中有一行我发现非常有用,我相信你以后也会这么觉得。定制协程,即一个新的CustomYieldInstruction类,意味着你现在可以用一个非常简单的方式来加入你自己的协程yield操作。来让我们看一个真实的例子。
一个真实世界的例子——一个错误修复
我最近在解决一个UI Dropdown组件的bug,Unity5.2的功能。当Time.timescale被设为0的时候,Dropdown组件将只调用一次,除非把timescale的值设为非0,它不会再被调用;经过一点调试以后,我们发现Show函数里面的问题。
Dropdown不为空,它阻止Dropdown被调用。
一旦展现出来,Dropdown会被最小化然后被摧毁,是的,它应该被摧毁,当时当timescale设为0的时候,这个并没有发生。
看下destroy函数,看你是否能发现这个问题。
文章的标题可能会对你有误导,但是WaitForSeconds导致问题的原因,WaitForSeconds使用变化的时间。这意味这如果你告诉WaitForSeconds等待1秒钟,而timscale是0.5,那么你实际等待的是2秒。所以你使用WaitForSeconds的时候,如果timescale是0那么意味这你将永远等待下去(除非timescale被设为非0)。这样Dropdown永远也不会被销毁。
解决方案
我们需要等待未经变化的时间,最简单的办法是加一个新的yield操作,一个WaitForSecondsRealtime类。很明显,如果我们开发人员没有意识到WaitForSeconds使用变化的时间,那么我们需要解决这个问题。WaitForSecondsRealtime这个名字应该有助于理解这个信息。我们还需要更新 WaitForSeconds的文档(文档并没有提到使用变化时间)。
这就是最近我如何发现CustomYieldInstruction,它是最近才添加的用于创建yield操作的。添加一个新的yield操作非常简单,下面是我们问题的解决方案。
任何定制的yield操作需要重载keepWaiting,一旦我们需要yield操作继续,我们只需要返回false.
下面是我们的修复:
在这个例子中,我们只是获取实际时间并且在每次获取的时候检查它。它没法再简单了—哦,等一下,因为我们现在有WaitUntil和WaitWhile 这些yield操作。用它们,我们可以提供一个delegaate来给我们的yiled操作
下面是另外一个方法来解决这个问题,假设我们需要5秒的延迟。
因此,这是一个简单的功能,但是有很大的潜能。我想这课学到的是:记住读发布公告,你永远不知道哪些是你需要的功能。如果你喜欢定制协程,你需要看下UnityEvents,另外一个你可能会错过的有用的功能。