やまちゃん(エンジニア)
【Unity】Destroyメソッドでオブジェクトが破棄されるタイミング
やまちゃん(エンジニア)
2024.03.01
IT技術
Destroyメソッドの使い方について
Unityでゲームを作る際、例えばキャラクターが弾を撃ち、敵を倒す場合、弾が敵に当たった時に弾のオブジェクトをシーン上から削除する必要が出てくるだろう。
使い方は以下の通り。
1
2// 特定のオブジェクトを破棄する
3GameObject bullet = GameObject.Find("Bullet");
4Destroy(bullet);
5
6// このスクリプトがついたオブジェクトを破棄する
7Destroy(gameObject);
ただし、Destroyはコンポーネントも削除できるので、書き方によってはオブジェクトは残ってしまう
1
2// このスクリプトを破棄する(オブジェクトは残る)
3Destroy(this);
4
5var canvasGroup = gameObject.GetComponent();
6// CanvasGroupのコンポーネントを破棄する(オブジェクトは残る)
7Destroy(canvasGroup);
Destroyメソッドでオブジェクトが破棄されるタイミング
本題のDestroyメソッドでオブジェクトが破棄されるタイミングは、
Destroyメソッドが呼ばれたフレームの最後
ライフサイクルのOnDestroyに当たる部分になる。
https://docs.unity3d.com/ja/2023.2/Manual/ExecutionOrder.html
実際に検証
コード:
1using UnityEngine;
2
3コード
4public class Gun : MonoBehaviour
5{
6 GameObject bullet;
7 int frameCount;
8
9 void Start()
10 {
11 bullet = GameObject.Find("Bullet");
12 frameCount = 0;
13 }
14
15 void Update()
16 {
17 frameCount += 1;
18 if (bullet != null)
19 {
20 // bulletがまだあったら破棄する
21 Destroy(bullet);
22 }
23
24 // Destroy後に判定する
25 if (bullet == null)
26 {
27 Debug.Log($"{frameCount}フレーム目: bullet is null");
28 }
29 else
30 {
31 Debug.Log($"{frameCount}フレーム目: bullet is not null");
32 }
33 }
34}
実行結果:
Destroyの後のif文が、1フレーム目はbulletがnullじゃない、2フレーム目以降はbulletがnullという判定になっていることが確認できる。
処理が多くなった際に、破棄したと思ったオブジェクトがDestroyメソッドと同一フレームでまだ破棄されておらず、オブジェクトの数にカウントされたりif文が想定通り判定されなかったりするので、注意が必要だ。
対策としてはnullを代入するなどが考えられる
1using UnityEngine;
2
3public class Gun : MonoBehaviour
4{
5 GameObject bullet;
6 int frameCount;
7
8 void Start()
9 {
10 bullet = GameObject.Find("Bullet");
11 frameCount = 0;
12 }
13
14 void Update()
15 {
16 frameCount += 1;
17 if (bullet != null)
18 {
19 // bulletがまだあったら破棄する
20 Destroy(bullet);
21 // 破棄したらその場でnullにする
22 bullet = null;
23 }
24
25 // Destroy後に判定する
26 if (bullet == null)
27 {
28 Debug.Log($"{frameCount}フレーム目: bullet is null");
29 }
30 else
31 {
32 Debug.Log($"{frameCount}フレーム目: bullet is not null");
33 }
34 }
35}
また、DestroyImmediateという即座に破棄されるメソッドもあるが、公式は推奨していないので、可能な限りDestroyを使おう。
ライトコードでは、エンジニアを積極採用中!
ライトコードでは、エンジニアを積極採用しています!社長と一杯しながらお話しする機会もご用意しております。そのほかカジュアル面談等もございますので、くわしくは採用情報をご確認ください。
採用情報へ