1. ホーム
  2. c#

[解決済み】Unityでゲームオブジェクトのすべての子をループスルーして破壊する方法?

2022-02-21 11:17:34

質問内容

以下のスクリプトをゲームオブジェクトにアタッチし、エディターでボタンをクリックすると実行されるようにしています。

public void ClearChildren() {
    Debug.Log(transform.childCount);
    float i = 0;
    foreach (Transform child in transform) {
        i += 1;
        DestroyImmediate(child.gameObject);
    }
    Debug.Log(transform.childCount);
}

これを見ると、元の childCount は13で、最終的な値は6です。さらに、すべての i これは、ループが7回しか実行されておらず、期待された13回ではないことを示しています。

最終的な値が0になるように、すべての子を削除するにはどうしたらよいでしょうか。参考までに、私が削除しようとしているchildrenは、ベンダーのスクリプトによって自動的に作成されたものです。また、このスクリプトを [ExecuteInEditMode] 参考までに

次のスクリプトも同じ動作で、もし childCount は 4 で始まり、2 で終わります。

public void ClearChildren() {
    Debug.Log(transform.childCount);
    for (int i = 0; i < transform.childCount; i++) {
        Transform child = transform.GetChild(i);
        DestroyImmediate(child.gameObject);
    }
    Debug.Log(transform.childCount);
} 

以下のように試すと、ランタイムエラーが発生します。 foreach という行があります。 InvalidCastException: 送信元の型から送信先の型にキャストできません。

public void ClearChildren() {
    Debug.Log(transform.childCount);
    foreach ( GameObject child in transform) {
        DestroyImmediate(child);
    }
    Debug.Log(transform.childCount);
}

解決方法は?

問題は、forループでObjectにアクセスしながら削除しようとしていることです。

こうすればいいのです。

  1. すべての子オブジェクトを検索し、配列に格納します。

  2. 別のループでそれらを破棄する

     public void ClearChildren()
     {
         Debug.Log(transform.childCount);
         int i = 0;
    
         //Array to hold all child obj
         GameObject[] allChildren = new GameObject[transform.childCount];
    
         //Find all child obj and store to that array
         foreach (Transform child in transform)
         {
             allChildren[i] = child.gameObject;
             i += 1;
         }
    
         //Now destroy them
         foreach (GameObject child in allChildren)
         {
             DestroyImmediate(child.gameObject);
         }
    
         Debug.Log(transform.childCount);
     }