# ScriptEngine::OnFixedUpdate **命名空间**: `XCEngine::Scripting` **类型**: `method` **头文件**: `XCEngine/Scripting/ScriptEngine.h` ## 签名 ```cpp void OnFixedUpdate(float fixedDeltaTime); ``` ## 当前实现行为 - 只在 `m_runtimeRunning` 为真时继续执行。 - 复制当前脚本顺序表,按顺序遍历。 - 本次回调真正传给脚本生命周期的是调用方传入的 `fixedDeltaTime` 参数。 - 对每个脚本要求同时满足: - `ShouldScriptRun(state)` - `EnsureScriptReady(state, true)` - `state.enabled == true` - 满足后调用运行时 `FixedUpdate` 生命周期。 - 每次生命周期调用后,`InvokeLifecycleMethod()` 还会立即触发 `SyncManagedFieldsToStorage()`。 ## 关键语义 - `EnsureScriptReady(state, true)` 不只是空检查;如果实例还不存在,它会创建实例,并补发 `Awake / OnEnable`。 - 因此某个脚本第一次真正进入 fixed step 调度前,可能会先完成实例创建和启用流程。 - `Start` 不在这里触发;它仍然会留到第一次 [OnUpdate](OnUpdate.md) 前补发。 ## 设计意义 复制顺序表再遍历,可以避免遍历过程中容器被增删时直接打乱当前帧顺序。 需要注意的是,[GetRuntimeFixedDeltaTime](GetRuntimeFixedDeltaTime.md) 返回的是另一条“运行时固定步长配置值”通道。当前 `OnFixedUpdate()` 并不会主动读取该配置并覆盖自己的参数,所以时间系统调用方应自行保证两者一致。 ## 托管侧可见性 - 当前 fixed tick 传给托管 `Time.deltaTime` 的,是这里的 `fixedDeltaTime` 实参。 - 托管 `Time.fixedDeltaTime` 读到的,则是 [GetRuntimeFixedDeltaTime](GetRuntimeFixedDeltaTime.md) 返回的配置值。 如果上层把两者配成不同值,脚本在同一轮 fixed update 里就可能同时读到两份不一致的时间数据。 ## 真实行为依据 - `engine/src/Scripting/ScriptEngine.cpp` - `engine/src/Scripting/Mono/MonoScriptRuntime.cpp` - `managed/XCEngine.ScriptCore/Time.cs` - `tests/Scripting/test_mono_script_runtime.cpp` ## 相关文档 - [SetRuntimeFixedDeltaTime](SetRuntimeFixedDeltaTime.md) - [GetRuntimeFixedDeltaTime](GetRuntimeFixedDeltaTime.md) - [OnUpdate](OnUpdate.md)