Destroyメソッド実行のタイミング
Unityのゲームオブジェクトを削除する場合、Destroyメソッドを使いますが、削除されるタイミングに注意する必要があります
Destroyメソッドでオブジェクトを削除
シーン構成
コード
using UnityEngine;
public class Test : MonoBehaviour
{
public GameObject obj;
void Start()
{
Destroy(obj);
Debug.Log((obj == null) ? "オブジェクトが参照できません" : "オブジェクトが参照できます");
}
private void Update()
{
Debug.Log((obj == null) ? "オブジェクトが参照できません" : "オブジェクトが参照できます");
Debug.Break();
}
}
実行結果
解説
UnityのDestroyメソッドの実装は公開されていませんが、基本的には指定されたUnityEngineオブジェクトに関連するリソースを解放し、ガベージコレクションのためにマークします。このメソッドは非同期に動作します。つまり、オブジェクトの実際の破壊はすぐには起こらず、次のフレーム、またはそれ以降のある時点で起こる可能性があるということです。
実際にゲームオブジェクトが削除されるのは、次のフレームのため、同じフレーム内でDestroyされるわけではありません
メソッドブロック内でDestroy文とオブジェクトがnullを前提としてコードを記述した場合、想定通りには実行されませんのでご注意ください
nullを代入してオブジェクトを削除
シーン構成
Destroyメソッドの時と同じです
コード
Destroyメソッドの代わりにnullを代入しています
ただし、この場合、シーン上からオブジェクトが削除されません
Unityの場合、実際は使えないコードになります
using UnityEngine;
public class Test : MonoBehaviour
{
public GameObject obj;
void Start()
{
obj = null;
Debug.Log((obj == null) ? "オブジェクトが参照できません" : "オブジェクトが参照できます");
}
private void Update()
{
Debug.Log((obj == null) ? "オブジェクトが参照できません" : "オブジェクトが参照できます");
Debug.Break();
}
}
実行結果
シーンのオブジェクトが残っています
アウトレット接続は、Destroyの場合、「Missing」でしたが、「None」になっています
結果もそれぞれ参照できない旨が表示されています
解説
nullを代入していますので、逐次実行されます
なのでnullチェックではすぐ判定されます
しかし、Unityの場合、ゲームオブジェクトはnullで削除されることが認められなイノで、実際はDestroyメソッドが必要です
Unityのゲームオブジェクトを削除する場合、Destroyメソッドを使いますが、削除されるタイミングに注意する必要があります
(おまけ)DestroyImmediateメソッドでオブジェクトを削除
シーン構成
コード
using UnityEngine;
public class Test : MonoBehaviour
{
public GameObject obj;
void Start()
{
DestroyImmediate(obj);
Debug.Log((obj == null) ? "オブジェクトが参照できません" : "オブジェクトが参照できます");
}
private void Update()
{
Debug.Log((obj == null) ? "オブジェクトが参照できません" : "オブジェクトが参照できます");
Debug.Break();
}
}
実行結果
解説
DestroyImmediateメソッドは、Destroyメソッドと違い即時実行されます
なので、フレームの更新タイミングに関係なく、このコード行の次のコードではnullになります
ただし、Unityでは代わりにDestroyを使うことが強く推奨されていますので特別な要件がない限り使わない方が無難です
ディスカッション
コメント一覧
まだ、コメントがありません