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

95 lines
2.6 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.
# MonoScriptRuntime::DestroyManagedObject
**命名空间**: `XCEngine::Scripting`
**类型**: `method`
**头文件**: `XCEngine/Scripting/Mono/MonoScriptRuntime.h`
## 签名
```cpp
bool DestroyManagedObject(MonoObject* managedObject);
```
## 作用
根据传入的托管包装对象,销毁它在原生运行时中对应的 `GameObject` 或组件。
## 当前实现行为
- 只有在运行时已初始化,且 `managedObject` 非空时才会继续。
- 函数会先切回当前 Mono app domain再读取对象的实际 `MonoClass`
### 当对象是 `GameObject` 包装对象时
- 读取 `managedGameObjectUUID`
- 必须能在当前 internal-call 活动场景里找到对应 `GameObject`
- 且该对象确实属于当前活动场景
- 满足条件后调用 `scene->DestroyGameObject(gameObject)`
### 当对象是组件包装对象时
- 必须是 `Component` 本体或其子类
- 先读取 `gameObjectUUID`
- 若它是脚本行为包装对象,还会继续读取 `scriptComponentUUID`
- 能精确定位到原生脚本组件时,会调用内部 `DestroyNativeComponentInstance(...)`
对于内建原生组件包装对象,当前支持:
- `Camera`
- `Light`
- `MeshFilter`
- `MeshRenderer`
以下类型当前不会被销毁:
- `Transform`
- 无法识别的组件类型
- 无法定位到有效原生对象的包装对象
## 组件销毁语义
当前底层 `DestroyNativeComponentInstance(...)` 会:
1. 拒绝销毁空组件和 `Transform`
2. 若组件当前启用,且宿主对象在层级中处于激活状态,则先调用 `OnDisable()`
3. 调用 `OnDestroy()`
4. 最后执行 `gameObject->RemoveComponent(component)`
这说明当前实现不是简单地把组件从数组里抹掉,而是尽量保持接近引擎生命周期语义的销毁顺序。
## 与托管侧 API 的关系
当前 `Object.Destroy(...)` 的 internal call 最终会走到这个方法:
```text
InternalCall_Object_Destroy
-> MonoScriptRuntime::DestroyManagedObject
```
因此它是托管脚本“请求销毁原生对象”的核心落点之一。
## 测试锚点
`tests/scripting/test_mono_script_runtime.cpp` 中的
- `UnityObjectApiSupportsHierarchyLookupAndDestroy`
直接覆盖了当前层级查询与销毁语义,包括:
- 子对象与父对象查询
- 组件查询
- 销毁后对象与组件是否真的从场景中消失
## 返回值
- 成功定位并销毁原生对象或组件时返回 `true`
- 其余情况返回 `false`
## 相关文档
- [MonoScriptRuntime](MonoScriptRuntime.md)
- [CreateManagedComponentWrapper](CreateManagedComponentWrapper.md)
- [DestroyScriptInstance](DestroyScriptInstance.md)