# 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)