【Unity】Destroy和DestroyImmediate的区别

来源:互联网 发布:网络诈骗的案例 编辑:程序博客网 时间:2024/05/21 10:20

情景:有一个父物体A,A有子物体B1.B2.B3……B10等10个子物体
那么现在若想移除B1—B10,该如何?
我能想到的最简单是这样做

    using UnityEngine;      using System.Collections;      /// <summary>      /// 脚本位置:将此脚本挂载到父物体A身上      /// 脚本功能:用于测试销毁所有子物体      /// </summary>      public class Parent : MonoBehaviour      {          void Start ()          {              for (int i = 0; i < transform.childCount; i++) {                  Destroy (transform.GetChild (i).gameObject);              }          }      }  
  • 第一眼看下去,好像没什么不对,粘贴到工程里试一试,也OK
    没错,这段程序没有问题的,但是不知道大家有没有注意
    Destroy里面的GetChild(i)为什么是i呢,i是不是从0到9?
    没错,i从0开始,i++肯定是一直递增的,但是它能不能加到9就是另外一回事了
    因为这取决于transform.childCount的值

  • 运行测试之后,所有子物体确实已经销毁,打印输出i的值,是0—9
    那么这一切都说明,当我们使用Destroy销毁物体的时候,程序不能立刻检测到这个物体被销毁了,所以获取子物体数量的时候,依然获取到的是有10个子物体

  • 所以,这个时候使用Destroy销毁对象的时候不是我们想象的那个样子
    我们想象的是什么样子?你怎么知道我在想什么

  • List大家应该都比较熟悉,当List中有10个对象的时候,如果RemoveAt掉了第0个,那么后面的9个对象都会向前移动,只要执行10次RemoveAt(0)那么就会清空List

  • 但是被Destroy的游戏对象不会发生类似List中移除对象的情况,销毁了第0个子物体,第1个子物体还在原来的位置,程序不能立即检测到到它被销毁了,需要过几帧之后才能检测到

如果想实现List一样的效果,那么需要使用DestroyImmediate这个方法
代码就变成这个样子

public class Parent : MonoBehaviour{    void Start ()    {          int count = transform.childCount;        for (int i = 0; i < count; i++) {              DestroyImmediate (transform.GetChild (0).gameObject);        }      }}  

最后,官方推荐使用Destroy代替DestroyImmediate

原因是DestroyImmediate是立即销毁,立即释放资源,做这个操作的时候,会消耗很多时间的,影响主线程运行
Destroy是异步销毁,一般在下一帧就销毁了,不会影响主线程的运行。

原创粉丝点击