Files
XCEngine/docs/api/XCEngine/Scripting/ScriptEngine/OnFixedUpdate.md

58 lines
2.2 KiB
Markdown

# 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)