world脚本具有许多用于编写应用程序逻辑的函数。世界脚本(init())的初始化函数用于创建对象并初始化世界负载上的所有其他必要资源。卸载世界时调用关闭函数(shutdown()),用于删除在脚本执行期间创建的资源以避免内存泄漏。
但是逐帧更新怎么样?在世界脚本中有三个块:
在世界脚本update()中,您可以在应用程序执行时将每个框架都调用所有函数。它用于实现任何逻辑。简而言之,您可以在update()中控制很多事情(无论是否与图形相关)。在这里你可以:
注意
不要在更新()中对刚体施加力和扭矩。否则,您将获得随每个渲染帧而变化的不稳定结果。所有连续操作必须在flush()内。
update()中设置的回调(例如,通过使用WorldTrigger或小部件回调)不会立即执行。它们将仅在调用下一个引擎函数时运行:即,在flush()之前,如果有(在当前帧中),或在下一次更新之前()(在下一帧中) - 无论先发生什么。
world脚本的flush()函数用于控制应用程序中的物理。此功能应用于连续操作,例如根据当前电机的RPM推动汽车前进,模拟持续吹风,执行即时碰撞响应(因为在单个渲染帧期间可以多次执行flush(),您可以处理多次反弹对象,当它们相互碰撞并监视它们时,update()只显示最终结果)等等。因此,在flush()中你可以:
注意对于flush()中可以做什么,有一些限制。由于主循环在刷新调用期间访问节点列表及其转换数据,因此您无法执行以下操作:
这些操作可能违反正在进行的渲染过程。
就像update()一样,如果在flush()中设置任何基于物理的回调或使用PhysicalTrigger,它们就不能立即执行,因为渲染过程已经在运行并且它们可以违反它。如果还有一个物理迭代要去,它们会在下一个flush()之前执行; 如果没有,则在下一个世界脚本update()之前。
如果要重新定位或转换,创建或删除物理回调返回的节点,工作流程如下:将它们存储在数组中,然后在update()中执行所有必要的操作。
世界脚本的render()函数是用于在节点状态更新后纠正行为的附加函数(例如,已在当前帧中播放蒙皮动画或粒子系统已生成其粒子)。
想象一下,当我们需要将一个对象(比方说,一把剑)附加到蒙皮网格角色的手上时。如果我们在update()函数中转换角色手骨并将其设置为剑,则附件将是松散的而不是精确的。剑不会紧紧握在手中,因为动画实际上是在执行了世界脚本update()之后播放的。这意味着,update()中返回的骨骼转换将用于前一帧。播放动画后执行世界脚本render(),这意味着您可以在此函数中获取当前帧的更新骨骼变换并将其设置为剑。
注意
使用render()仅用于更正目的; 否则,这将增加主循环时间。所有其他函数应放在update()或flush()(physics)中。