本文已参与「新人创作礼」活动,一起开启掘金创作之路。
1、故事背景
由于某些原因,要将脚本销毁掉,然后重新添加、配置。
这样,问题出现了,脚本一次能加上,一次加不上,就这样循环。Debug显示,添加脚本前有些时候(奇数次)的脚本依然存在,未被销毁。
知道了问题所在,就开始寻求解决办法。
2、Destroy与DestroyImmediate的区别
2.1 DestroyImmediate
正如它的名字显示所示(Immediate意思为立刻、立即),当GameObject类型参数传递进来时,只要一执行该函数,则该游戏物体就会立刻销毁,不会等到当前帧结束之后才销毁物体,并将目标置为null,且将目标的所有上层引用置空,如用DestroyImmediate销毁object下的所子物体后object.childcount将变为0。
2.2 Destroy
Destroy则在本帧结束前,渲染之前销毁目标和上层引用。不会立即销毁,Destroy调用后,目标数据仍然存在,不为null,上层引用也正常。
销毁物体后,childcount仍然保持不变,这常会造成其它地方的逻辑出错,子结点已经销毁了却还能取到,因此,我们应该将子结点从父物体摘除,rootTrans.DetachChildren();这样其它地方代码再获取子结点及其数量时就不导致逻辑出错了。
3、官方文档
3.1 Object.DestroyImmediate
public static void DestroyImmediate (Objectobj, bool allowDestroyingAssets= false);
3.1.1 参数
| obj | 要销毁的对象 |
|---|---|
| allowDestroyingAssets | 设置为 true 将允许销毁资源 |
3.1.2 描述
立即销毁对象 /obj/。强烈建议您改用 Destroy。
该函数应只在编写 Editor 代码时使用,因为在编辑模式下, 永远不会调用延迟销毁。 在游戏代码中,您应该改用 Object.Destroy。Destroy 始终延迟进行 (但在同一帧内执行)。 使用该函数时要务必小心,因为它可以永久销毁资源! 另请注意,切勿循环访问数组并销毁正在迭代的元素。这会导致严重的问题(这是一条通用的编程实践,而不仅仅是在 Unity 中)。
3.2 Object.Destroy
public static void Destroy ([Object](https://docs.unity3d.com/cn/2019.4/ScriptReference/Object.html) obj, float t= 0.0F);
3.2.1 参数
| obj | 要销毁的对象 |
|---|---|
| t | (可选)销毁对象前的延迟。 |
3.2.2 描述
移除 GameObject、组件或资源。
在当前更新循环之后立即销毁或从现在开始 t 秒(如果指定了时间)后销毁对象 obj。 如果 obj 是 Component,则此方法会从 GameObject 移除该组件并将它销毁。 如果 obj 是 GameObject,则会销毁该 GameObject、其所有组件以及该 GameObject 的所有变换子项。 实际的对象销毁操作始终延迟到当前更新循环结束,但始终在渲染前完成。