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

2.6 KiB
Raw Blame History

MonoScriptRuntime::DestroyManagedObject

命名空间: XCEngine::Scripting

类型: method

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

签名

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 最终会走到这个方法:

InternalCall_Object_Destroy
-> MonoScriptRuntime::DestroyManagedObject

因此它是托管脚本“请求销毁原生对象”的核心落点之一。

测试锚点

tests/Scripting/test_mono_script_runtime.cpp 中的

  • UnityObjectApiSupportsHierarchyLookupAndDestroy

直接覆盖了当前层级查询与销毁语义,包括:

  • 子对象与父对象查询
  • 组件查询
  • 销毁后对象与组件是否真的从场景中消失

返回值

  • 成功定位并销毁原生对象或组件时返回 true
  • 其余情况返回 false

相关文档