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);
      }


    }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM