99 lines
3.0 KiB
Markdown
99 lines
3.0 KiB
Markdown
# MonoScriptRuntime::TryGetClassFieldMetadata
|
||
|
||
**命名空间**: `XCEngine::Scripting`
|
||
|
||
**类型**: `method`
|
||
|
||
**头文件**: `XCEngine/Scripting/Mono/MonoScriptRuntime.h`
|
||
|
||
## 签名
|
||
|
||
```cpp
|
||
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](TryGetClassFieldDefaultValues.md) 或字段同步链里。
|
||
|
||
## 返回值语义
|
||
|
||
- `true`
|
||
- 类存在;即使类存在但筛完没有可用字段,也仍然可能返回 `true` 且 `outFields` 为空。
|
||
- `false`
|
||
- 类不存在,无法找到对应类元数据。
|
||
|
||
## 测试锚点
|
||
|
||
`tests/Scripting/test_mono_script_runtime.cpp` 里的
|
||
`ClassFieldMetadataListsSupportedPublicInstanceFields`
|
||
已经明确验证:`HiddenFlag` 会进入字段元数据,而未标注 private 字段不会。
|
||
|
||
## 相关文档
|
||
|
||
- [MonoScriptRuntime](MonoScriptRuntime.md)
|
||
- [TryGetClassFieldDefaultValues](TryGetClassFieldDefaultValues.md)
|
||
- [IScriptRuntime::TryGetClassFieldMetadata](../../IScriptRuntime/TryGetClassFieldMetadata.md)
|
||
- [Scripting Runtime And Field Model](../../../../_guides/Scripting/Scripting-Runtime-And-Field-Model.md)
|