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

3.0 KiB
Raw Blame History

MonoScriptRuntime::TryGetClassFieldMetadata

命名空间: XCEngine::Scripting

类型: method

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

签名

bool TryGetClassFieldMetadata(
    const std::string& assemblyName,
    const std::string& namespaceName,
    const std::string& className,
    std::vector<ScriptFieldMetadata>& outFields) const override;

作用

返回指定脚本类当前“可进入字段模型”的字段元数据列表。

这里返回的不是类里声明的全部字段,而是经过 Mono 运行时筛选后的字段集合。

当前实现行为

  1. 先清空 outFields
  2. (assemblyName, namespaceName, className) 查缓存里的类元数据。
  3. 如果类不存在,返回 false,并保持 outFields 为空。
  4. 如果类存在:
    • 遍历 metadata->fields
    • 复制成 ScriptFieldMetadata{name, type}
    • 最终按字段名排序后返回 true

因此,这个方法本身不再扫描程序集;它只读取初始化阶段已经构建好的类缓存。

字段筛选规则

字段集合来源于 DiscoverScriptClassesInImage(...) 的筛选结果。当前真实规则是:

  • 排除 static
  • 排除 const / literal
  • 排除 readonly / init-only
  • 接受:
    • public 实例字段
    • 或带 [SerializeField]private 实例字段
  • 再要求字段类型属于当前支持集合

这意味着“private”本身不是问题问题在于它有没有显式进入序列化/字段模型。

典型例子

managed/GameScripts/FieldMetadataProbe.cs 当前很好地展示了这些边界:

  • 会被发现:
    • Health
    • Speed
    • Label
    • SpawnPoint
    • State
    • Target
    • HiddenFlag
  • 不会被发现:
    • SharedCounter
    • IgnoredPrivateCounter
    • UnsupportedRotation

其中 HiddenFlag 能被发现,正是因为它是 [SerializeField] private bool

为什么这很重要

这条规则直接决定了:

  • Inspector / 字段编辑 UI 能看到哪些字段
  • 场景序列化允许存哪些字段
  • 运行时字段默认值和字段同步覆盖哪些字段

如果一个字段没进入这里,它后续也不会出现在 TryGetClassFieldDefaultValues 或字段同步链里。

返回值语义

  • true
    • 类存在;即使类存在但筛完没有可用字段,也仍然可能返回 trueoutFields 为空。
  • false
    • 类不存在,无法找到对应类元数据。

测试锚点

tests/Scripting/test_mono_script_runtime.cpp 里的 ClassFieldMetadataListsSupportedPublicInstanceFields 已经明确验证:HiddenFlag 会进入字段元数据,而未标注 private 字段不会。

相关文档