任务调度器协调游戏运行时每帧完成的任务,即使在游戏暂停时。这些任务包括检测玩家输入、动画角色、更新物理模拟以及恢复处于 task.wait() 状态的脚本。
虽然可能有多个任务在运行,但任务调度器可能会过载,特别是在以下情况下:
- 使用自定义角色装备或输入方案。
- 自己动手动画部件(而不是使用 Animator)。
- 严重依赖精确的物理。
- 定期复制对象。
RunService
逐帧添加任务的最直接方式是通过 RunService 的以下成员:
调度器优先级
任务调度器按以下顺序对任务进行分类和完成。有些任务可能不会在某一帧中执行工作,而其他任务可能会多次运行。
* 在 RunService.Heartbeat 中的脚本执行取决于您游戏的 Workspace.SignalBehavior 设置。请参见 延迟事件。
最佳实践
为了构建性能优秀、注重效率的游戏,请注意以下事项:
除非绝对必要,否则不要将函数连接/绑定到渲染步骤。 只有在输入后但在渲染之前必须执行的任务应以这种方式进行,比如相机移动。为了严格控制顺序,应使用 BindToRenderStep() 而不是 PreRender。
小心管理物理状态。 PreSimulation 发生在物理之前,而 PostSimulation 发生在物理之后。因此,影响物理状态的游戏逻辑应在 PreSimulation 中处理,例如设置部件的 Velocity。相反,依赖或响应物理状态的游戏逻辑应在 PostSimulation 中处理,例如读取部件的 Position 以检测它们何时进入定义的区域。
Motor6D 变换变化应在 PreSimulation 事件中进行。 如果不这样做,Animators 将在下一帧覆盖更改。即使没有 Animator,PreSimulation 是在 Motor6D.Transform 应用于部件位置之前最后一个触发的 Luau 事件。