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

6.3 KiB
Raw Blame History

MonoScriptRuntime

命名空间: XCEngine::Scripting

类型: class

头文件: XCEngine/Scripting/Mono/MonoScriptRuntime.h

描述: 基于 Mono 的脚本运行时实现,负责程序集解析与加载、类发现、实例创建、字段桥接、默认值读取和生命周期调用。

概览

MonoScriptRuntime 是当前唯一的真实托管脚本后端。它把 ScriptEngine 提供的抽象调用翻译成 Mono 世界里的具体动作:

  • 初始化 root domain 和 app domain。
  • 加载脚本核心程序集与游戏程序集。
  • 发现继承 MonoBehaviour 的可用脚本类,并缓存生命周期方法与字段元数据。
  • 读取类字段默认值。
  • 创建和销毁脚本实例。
  • 通过 internal call 让托管脚本访问原生 GameObjectTransformCamera 等能力。
  • 把本地字段覆盖写入托管实例,并在生命周期之后同步回 ScriptFieldStorage

Settings

构造函数接收一个 Settings 结构体,当前公开字段如下:

字段 说明
assemblyDirectory 程序集目录;若 coreAssemblyPath / appAssemblyPath 缺失,会以它为基准推导 DLL 路径。
corlibDirectory Mono 解析 mscorlib.dll 的目录;为空时会回退到 assemblyDirectorycoreAssemblyPath 所在目录。
coreAssemblyPath XCEngine.ScriptCore.dll 的完整路径。
appAssemblyPath GameScripts.dll 的完整路径。
coreAssemblyName 脚本核心程序集名,默认 XCEngine.ScriptCore
appAssemblyName 应用程序集名,默认 GameScripts
baseNamespace 核心托管 API 的命名空间,默认 XCEngine
baseClassName 作为脚本基类查找入口的类型名,默认 MonoBehaviour

ResolveSettings() 会在构造时和 Initialize() 前再次运行,补全目录和程序集路径。因此只提供 assemblyDirectory 也是合法用法;tests/scripting/test_project_script_assembly.cpp 就是基于项目脚本程序集目录这样初始化的。

生命周期

  • 构造时接收一份 Settings,并做路径补全。
  • Initialize 会完成完整 Mono 初始化流程。
  • Shutdown 会销毁 app domain、清空类缓存与实例缓存。
  • 析构会自动调用 Shutdown()

设计要点

  • ScriptEngine 不直接碰 Mono API所有后端细节收敛在这个类里。
  • 类缓存和实例缓存都基于稳定键,便于场景重建、类切换和实例回绑。
  • TryGetClassFieldDefaultValues() 会创建一个临时托管对象并读取字段值,因此脚本字段默认值可以反映 C# 初始化表达式,而不只是原生零值。
  • CreateScriptInstance() 会先注入上下文 UUID再把本地存储里同名且类型匹配的字段写入托管实例。
  • SyncManagedFieldsToStorage() 只回写本地已有字段,保证运行时不会把临时字段偷偷持久化到场景。

当前实现边界

  • 当前只发现应用程序集中的非抽象 MonoBehaviour 子类。
  • 支持的公共字段类型只覆盖 float / double / bool / int32 / uint64 / string / Vector2 / Vector3 / Vector4 / GameObject
  • TryGetAvailableScriptClasses()GetScriptClassNames() 和字段元数据查询都要求运行时已经初始化完成。
  • SyncManagedFieldsToStorage() 只会回写已经存在于 ScriptFieldStorage 中且类型仍匹配的字段;运行时临时字段不会自动持久化。
  • OnRuntimeStop() 只清理当前活动场景与实例,不会做完整 Shutdown();程序集和类缓存会保留到显式 Shutdown() 或析构。
  • 目前没有程序集热重载、增量编译监听或多场景并发运行支持。

公开方法

方法 说明
Constructor 创建 Mono 运行时对象并解析设置。
Destructor 析构时执行 Shutdown()
Initialize 初始化 Mono 域并发现脚本类。
Shutdown 关闭当前 Mono 运行时。
GetLastError 读取最近一次错误描述。
IsClassAvailable 查询脚本类是否已发现。
GetScriptClassNames 返回已发现脚本类名列表。
IsInitialized() 判断运行时是否已完成初始化。
GetSettings() 返回已解析的运行时设置。
TryGetAvailableScriptClasses 返回完整脚本类描述列表。
TryGetClassFieldMetadata 读取脚本类字段元数据。
TryGetClassFieldDefaultValues 读取脚本类字段默认值。
HasManagedInstance 判断某脚本组件是否已有托管实例。
GetManagedInstanceCount 返回当前托管实例数。
GetManagedInstanceObject 读取托管对象裸指针。
CreateManagedComponentWrapper 为原生组件创建托管包装对象。
TryGetFieldValue 直接读取托管实例字段。
OnRuntimeStart 启动脚本运行时上下文。
OnRuntimeStop 停止当前运行场景的托管上下文。
TrySetManagedFieldValue 写托管字段。
TryGetManagedFieldValue 读托管字段。
SyncManagedFieldsToStorage 回写本地字段缓存。
CreateScriptInstance 创建脚本实例。
DestroyScriptInstance 销毁脚本实例。
InvokeMethod 调用生命周期方法。

真实行为依据

  • engine/src/Scripting/Mono/MonoScriptRuntime.cpp
  • tests/scripting/test_mono_script_runtime.cpp
  • tests/scripting/test_project_script_assembly.cpp

相关文档