zoukankan      html  css  js  c++  java
  • UNITY Destroy()和DestroyImadiate()的区别

    using System.Collections;
    using System.Collections.Generic;
    using System.Timers;
    using UnityEngine;
    using System.Diagnostics;
    public class testdestroy : MonoBehaviour {
    
        GameObject cubeGo;
        Transform rootTrans;
        // Use this for initialization
    
        Stopwatch timer;
        void Start () {
            cubeGo = GameObject.Find("Cube");
            rootTrans = GameObject.Find("root").transform;
    
            timer = new Stopwatch();
        }
        
        // Update is called once per frame
        void Update () {
            if (Input.GetKey(KeyCode.LeftControl))
            {
                var go = Instantiate(cubeGo);
                go.transform.SetParent(rootTrans);
                
            }
            else if (Input.GetKey(KeyCode.A))
            {//11111111111
                for (int i = 0; i < rootTrans.GetChildCount(); ++i)
                {
                    timer.Reset();
                    timer.Start();
                    Destroy(rootTrans.GetChild(i).gameObject);
                    timer.Stop();
    
                    UnityEngine.Debug.Log("1:time elipsed===:" + timer.Elapsed);
                }
    
                rootTrans.DetachChildren();
            }
            else if (Input.GetKey(KeyCode.D))
            {//2222222222
                while (true)
                {
                    var cc = rootTrans.childCount;
                    //UnityEngine.Debug.Log("cc============================" + cc);
                    if (cc == 0)
                        break;
                    timer.Reset();
    
                    timer.Start();
                    DestroyImmediate(rootTrans.GetChild(0).gameObject);
                    timer.Stop();
    
                    UnityEngine.Debug.Log("2:time elipsed===:" + timer.Elapsed);
                }
    
            }
            else if (Input.GetKey(KeyCode.F))
            {
                DestroyImmediate(cubeGo.transform);
            }
        }
    }
    1,DestroyImmediate立即销毁目标,并将目标置为null,且将目标的所有上层引用置空,如用DestroyImmediate销毁OBJ下的所子物体后 OBJ.childcount将变为0,见代码//22222222222
    2,Destroy则在本帧结束前,渲染之前销毁目标和上层引用。不会立即销毁,Destroy调用后,目标数据仍然存在,不为null,上层引用也正常。见代码//111111111处,因为销毁物体后,childcount
    仍然保持不变,这常会造成其它地方的逻辑出错,子结点已经销毁了却还能取到,因此,我们应该将子结点从父物体摘除,rootTrans.DetachChildren();这样其它地方代码再获取子结点及其数量时就不导致逻辑出错了。

    3,基于上述原理,测试Destroy和DestroyImmediate的时间占用,发现后者几乎是前者的10倍。

    补充:
        void Start () {
            var root = gameObject.transform;
            for (var i = 0; i < root.childCount; ++i)
            {//方式一,正确删除所有子结点
                var c = root.GetChild(i).gameObject;
                GameObject.Destroy(c);
            }
            for (var i = 0; i < root.childCount; ++i)
            {//方式二,删不干净,会有一些剩余节点
                var c = root.GetChild(0).gameObject;
                GameObject.DestroyImmediate(c);
            }
            for (var i = 0; i < root.childCount; ++i)
            {//方式三,删不干净,会有一些剩余节点,只删除了偶数节点0,2,4,6,剩余奇数节点1,3,5,7
                var c = root.GetChild(i).gameObject;
                GameObject.DestroyImmediate(c);
            }
            while (root.childCount > 0)
            {//方式四,正确删除所有子结点
                var c = root.GetChild(0).gameObject;
                GameObject.DestroyImmediate(c);
               }
      

          for (int i = go.childCount - 1; i >= 0; i--) {//方式五,正确删除所有子结点
            GameObject.DestroyImmediate(go.GetChild (i).gameObject);
          }

    
        }
  • 相关阅读:
    python脚本2_输入2个数比较大小后从小到大升序打印
    python脚本1_给一个半径求圆的面积和周长
    配置双机互信
    如何在 CentOS7 中安装 Nodejs
    Git 服务器搭建
    docker安装脚本
    CentOS7下安装Docker-Compose
    Linux 文件锁
    6 系统数据文件和信息
    bash脚本编程之二 字符串测试及for循环
  • 原文地址:https://www.cnblogs.com/timeObjserver/p/6679632.html
Copyright © 2011-2022 走看看