【Unity】Destroyでオブジェクトが削除されるタイミング

投稿者: | 2020-06-19

シーンに5つの球があります。Start()で球をすべて検索し配列に入れ、配列の要素数を表示すると5個です。

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

public class DestroyTestScript : MonoBehaviour
{
    GameObject[] spheres;
    int n = 0;

    // Start is called before the first frame update
    void Start()
    {
        spheres = GameObject.FindGameObjectsWithTag("Sphere"); // 球を検索
        Debug.Log("1回目: " + spheres.Length + "個"); // 球の数を表示
    }

    // Update is called once per frame
    void Update()
    {
        // Eキーを押した次のフレーム
        if (n == 1)
        {
            spheres = GameObject.FindGameObjectsWithTag("Sphere"); // 球を検索
            Debug.Log("3回目: " + spheres.Length + "個"); // 球の数を表示

            n = 0;
        }
        
        // Eキーを押したとき
        if (Input.GetKeyDown(KeyCode.E))
        {
            Destroy(spheres[0]); // 1つの球を削除

            spheres = GameObject.FindGameObjectsWithTag("Sphere"); // 球を検索
            Debug.Log("2回目: " + spheres.Length + "個"); // 球の数を表示

            n++;
        }        
    }
}

その後、Eキーを押すと球のうち1つをDestroy()で破壊してから、同じフレームで球を再検索して配列に入れ、その要素数を表示し、次のフレームでも同様に球の再検索と数の表示をします。

すると、球の破壊と同じフレームではまだ5個の球が検索されて、次のフレームでは球が1つ減っていました。

このようにDestroy()の第2引数を指定しなくても、すぐに破壊されるわけではないようです。スクリプトリファレンスを見ると、現在のUpdate()の後に破壊されるとあります。https://docs.unity3d.com/ja/current/ScriptReference/Object.Destroy.html

なので、破壊と同時に再検索して、次以降のフレームで要素を取得するとエラーがでました。

void Update()
{
    // Eキーを押した次のフレーム
    if (n == 1)
    {
        /*
        spheres = GameObject.FindGameObjectsWithTag("Sphere"); // 球を検索
        Debug.Log("3回目: " + spheres.Length + "個"); // 球の数を表示      
        */

        foreach (GameObject s in spheres)
        {
            // 半分埋める
            Vector3 pos = s.transform.position;
            pos.y -= 0.5f;
            s.transform.position = pos;
        }

        n = 0;
    }
        
    // Eキーを押したとき
    if (Input.GetKeyDown(KeyCode.E))
    {
        Destroy(spheres[0]); // 1つの球を削除

        spheres = GameObject.FindGameObjectsWithTag("Sphere"); // 球を検索
        Debug.Log("2回目: " + spheres.Length + "個"); // 球の数を表示

        n++;
    }        
}

MissingReferenceException: The object of type ‘GameObject’ has been destroyed but you are still trying to access it.
Your script should either check if it is null or you should not destroy the object.

なので、オブジェクトを削除してから再度同じタグのオブジェクトを検索したいときは、次以降のフレームで行うといいと思います。

コメントを残す

メールアドレスが公開されることはありません。