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

79 lines
5.2 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Scripting
**命名空间**: `XCEngine::Scripting`
**类型**: `module`
**描述**: 提供脚本组件数据模型、字段覆盖存储、运行时调度器以及可替换的托管脚本后端抽象。
## 概览
当前脚本模块已经形成一条比较明确的“数据层 -> 调度层 -> 后端层”链路:
1. [ScriptComponent](ScriptComponent/ScriptComponent.md) 挂在 `GameObject` 上,保存程序集名、命名空间、类名、组件 UUID 和 [ScriptFieldStorage](ScriptFieldStorage/ScriptFieldStorage.md)。
2. [ScriptEngine](ScriptEngine/ScriptEngine.md) 在运行时收集场景内所有脚本组件,按 `(gameObjectUUID, scriptComponentUUID)` 跟踪实例状态,并统一驱动生命周期。
3. [IScriptRuntime](IScriptRuntime/IScriptRuntime.md) 定义“类发现、字段元数据、默认值读取、实例创建、生命周期调用、字段同步”的统一契约。
4. [NullScriptRuntime](NullScriptRuntime/NullScriptRuntime.md) 负责在没有真实托管后端时兜底,让脚本数据层和编辑流程仍然可工作。
5. [Mono](Mono/Mono.md) 子目录中的 [MonoScriptRuntime](Mono/MonoScriptRuntime/MonoScriptRuntime.md) 是当前唯一的真实托管后端,负责加载 `XCEngine.ScriptCore.dll``GameScripts.dll`、发现脚本类、创建托管实例并完成字段桥接。
如果从引擎分层角度理解:
- `ScriptComponent + ScriptFieldStorage` 是可序列化的数据层。
- `ScriptEngine` 是场景运行时的调度层。
- `IScriptRuntime`/`MonoScriptRuntime` 是托管执行后端。
## 设计要点
- 场景序列化只依赖 `ScriptComponent``ScriptFieldStorage`,不依赖 Mono 是否已经初始化。
- 字段模型分成“类声明默认值、存储覆盖值、活体托管值”三层,便于 Inspector 和调试工具说明字段来源。
- `ScriptEngine` 把生命周期顺序、运行中生成对象追踪、类切换重建都集中在一处。
- `IScriptRuntime` 让主流程只依赖契约,后续可以接别的托管后端,而不是把 Mono API 直接扩散到引擎各处。
## 当前运行链路
1. `SceneRuntime` 启动场景时调用 `ScriptEngine::OnRuntimeStart(scene)`
2. `ScriptEngine` 先通知当前运行时启动,再递归收集场景里现有的 `ScriptComponent`,同时订阅 `Scene::OnGameObjectCreated()` 以追踪运行中创建的新对象。
3. 对满足运行条件的组件,运行时创建托管实例;`MonoScriptRuntime` 会先把 `ScriptFieldStorage` 中同名且类型匹配的字段写入实例。
4. `ScriptEngine` 统一按 `Awake -> OnEnable -> Start -> FixedUpdate/Update/LateUpdate` 驱动生命周期。
5. 每次生命周期调用后,运行时执行 `SyncManagedFieldsToStorage()`;当前 Mono 实现只会回写“本地已存在且类型仍匹配”的字段。
6. 编辑器或调试工具可通过 `ScriptEngine::TryGetScriptFieldModel()` / `TryGetScriptFieldSnapshots()` 看到字段默认值、覆盖值、活体值以及 `StoredOnly` / `TypeMismatch` 等诊断状态。
## 项目程序集来源
`XCENGINE_ENABLE_MONO_SCRIPTING` 打开时,`managed/CMakeLists.txt` 会构建两类程序集:
- 引擎脚本核心程序集:`XCEngine.ScriptCore.dll`
- 游戏脚本程序集:`GameScripts.dll`
除了测试用的 `build/managed` 输出CMake 还会把项目 `project/Assets/**/*.cs` 编译到 `project/Library/ScriptAssemblies/GameScripts.dll``MonoScriptRuntime::Settings` 可以直接指向该目录,因此项目资产脚本和默认字段值已经进入当前文档的真实行为范围。
## 当前实现边界
- 当前公开支持的脚本字段类型是有限集合:标量、字符串、`Vector2/3/4``GameObject` 引用。
- 生命周期覆盖 `Awake / OnEnable / Start / FixedUpdate / Update / LateUpdate / OnDisable / OnDestroy`
- `NullScriptRuntime` 只是桥接占位,不会真正执行脚本代码,也不会返回脚本类列表或字段默认值。
- `MonoScriptRuntime` 目前只发现应用程序集中的非抽象 `MonoBehaviour` 子类,不做热重载、域增量刷新或完整编辑器脚本生态。
- 字段同步目前不会自动把“运行中新增但本地没有声明”的字段持久化下来。
## 头文件
- [IScriptRuntime](IScriptRuntime/IScriptRuntime.md) - `IScriptRuntime.h`
- [NullScriptRuntime](NullScriptRuntime/NullScriptRuntime.md) - `NullScriptRuntime.h`
- [ScriptComponent](ScriptComponent/ScriptComponent.md) - `ScriptComponent.h`
- [ScriptEngine](ScriptEngine/ScriptEngine.md) - `ScriptEngine.h`
- [ScriptField](ScriptField/ScriptField.md) - `ScriptField.h`
- [ScriptFieldStorage](ScriptFieldStorage/ScriptFieldStorage.md) - `ScriptFieldStorage.h`
- [Mono](Mono/Mono.md) - `Mono/`
## 相关指南
- [Scripting Runtime And Field Model](../../_guides/Scripting/Scripting-Runtime-And-Field-Model.md) - 解释当前脚本系统如何把场景、脚本字段缓存和 Mono 运行时衔接起来,以及为什么这样设计。
- [Project Script Assembly And Field Sync](../../_guides/Scripting/Project-Script-Assembly-And-Field-Sync.md) - 解释 `project/Assets/**/*.cs` 如何进入 `GameScripts.dll`,以及默认值、存储覆盖和活体字段如何相互覆盖。
## 相关文档
- [SceneRuntime](../Scene/SceneRuntime/SceneRuntime.md)
- [Scene](../Scene/Scene.md)
- [上级目录](../XCEngine.md)
- [API 总索引](../../main.md)