Unity(C#)初心者・入門者向けチュートリアル ひよこのたまご

AndroidやiOS向けアプリを簡単に作れるゲーム開発環境Unity(ユニティ)の使い方を、チュートリアル方式で一緒に学びましょう!

DestroyとDestroyImmediateの違い

gameObjectを破壊してHierarchy上から消し去りたい時に、よくDestroyメソッドが使われます!
が、Destroyで破壊されたgameObjectは実はまだ裏側で存在しています!(オブジェクトの数を確認すると分かります)
完全に消し去りたい場合には、Destroyの代わりにDestroyImmediateを使います!
(Immediate=即座)

DestroyとDestroyImmediateの違い

using System.Linq;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class TestScript : MonoBehaviour {

	// Use this for initialization
	void Start () {
        // 全子オブジェクトを取得
        var childArray = GetComponentsInChildren<Transform>().Where(t => gameObject != t.gameObject).ToArray();
        // 子オブジェクトの数を確認
        Debug.Log(childArray.Length);
        // 先頭の子オブジェクトをDestroyImmediate
        DestroyImmediate(childArray[0].gameObject);
        // 再度子オブジェクトの数を確認
        Debug.Log(GetComponentsInChildren<Transform>().Where(t => gameObject != t.gameObject).ToArray().Length);
        // 2番目の子オブジェクトをDestroy
        Destroy(childArray[1].gameObject);
        // 再度子オブジェクトの数を確認
        Debug.Log(GetComponentsInChildren<Transform>().Where(c => gameObject != c.gameObject).ToArray().Length);
    }
}

結果
f:id:hiyotama:20180313174632p:plain

DestroyImmediateでは子オブジェクトの数が減りましたが、
Destroyでは減りません!

ちなみに…

using System.Linq;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class TestScript : MonoBehaviour {

	// Use this for initialization
	void Start () {
        StartCoroutine(DestroyObject());
    }

    IEnumerator DestroyObject() {
        var childArray = GetComponentsInChildren<Transform>().Where(t => gameObject != t.gameObject).ToArray();
        Debug.Log(childArray.Length);
        DestroyImmediate(childArray[0].gameObject);
        Debug.Log(GetComponentsInChildren<Transform>().Where(t => gameObject != t.gameObject).ToArray().Length);
        Destroy(childArray[1].gameObject);
        // 1フレーム待機
        yield return null;
        Debug.Log(GetComponentsInChildren<Transform>().Where(c => gameObject != c.gameObject).ToArray().Length);
    }
}

結果
f:id:hiyotama:20180313175725p:plain

コルーチンで1フレーム待ってあげると、ちゃんと減っています!
1つの処理の中で即座にDestroyしたい場合にはDestroyImmediateをお試しください!

・・・と思ったのですが、公式では非推奨としているようです・・・
Object.DestroyImmediate
知識としてストックしておくにとどめておいたほうがよさそうです!