汎用C#でコーディングしている場合、特定のタイプのオブジェクトのみを格納するリストを作成できます。誤ってそのタイプ以外のものをリストに追加しようとすると、すぐに通知され、問題をすばやく修正できます。
List<Foo> my_list = new List<Foo>(); my_list.Add(Bar) //Error
ただし、私はUnityを使用する場合、スクリプトをGameObjectにアタッチする必要があり、それをリストに保存する必要があります。
List<GameObject> my_list = new List<GameObject>(); GameObject Foo = new GameObject; Foo.AddComponent<Foo>(); GameObject Bar = new GameObject; Bar.AddComponent<Bar>(); my_list.Add(Foo) //Fine my_list.Add(Bar) //Works, but I don"t want it to
リストに「Foo」のみを保存したい「GameObjects(Fooコンポーネントを備えたGameObjects)ですが、どのタイプのGameObjectも誤って保存してしまうのを防ぐことはできません。そのため、問題をデバッグしようとして頭をかきむしりました。
List<GameObject(Foo)> my_list
の効果を持つようにGameObjectをサブタイプ化する方法はありますか?配列でもそれを行う方法はありますか?
回答
特定のComponent
divを含むGameObject
タイプのみを保存する場合>要素の場合、最も簡単な解決策は、リストタイプに特定のComponent
を使用することです。
b ase Component
クラスには、「host GameObject
」への参照が含まれています。リストを特定のComponent
に制限しても、それぞれのGameObject
にアクセスできます。
以下のスクリプトは、一般的なCollider
クラスでこれを管理する方法の例です。要素を追加するための特別なメソッドを含めました。このメソッドは、bool
を返し、Collider
が実際に
、およびリスト内のインデックスに基づいて必要なGameObject
を直接取得するための特別なメソッド。
///<summary>A list of generic collider types, populated through the inspector.</summary> public List<Collider> colliders; ///<summary>Adds a collider reference to the list, using the host game object.</summary> ///<param name="targetGameObject">The game object to reference the collider from./<param> ///<returns>True, if the game object contained a collider, else returns false.</returns> public bool AddGameObjectToList(GameObject targetGameObject) { Collider targetCollider = GameObject.GetComponent<Collider>(); if(targetCollider == null) { return false; } else { colliders.Add(target collider); return true; } } <summary>Provides direct reference to the game object of a certain element in the list.</summary> ///<param name="index">The index pointer to the collider holding the desired game object.<param> ///<returns>The game object associated with the provided index in the component list.</returns> public GameObject GetGameObject(int index) { return colliders[index].GameObject; }
ボーナスポイントについては、ジェネリックを使用して、これを基本クラスに変えることができます。 Component
クラスでベースのジェネリックを使用すると、任意のコンポーネントを表すインスタンスをその場で作成できます。すべてのコンポーネントはComponent
から継承します。
回答
- 各タイプ。つまり、foo.cs、bar.csなど
- 目的のタイプのリストを作成します。つまり、リストfoolist
-
fooにbarインスタンスを追加しようとすると、エラーが発生します。
public Transform fooObjects; List<Foo> fooList; Bar b; // Use this for initialization void Awake () { fooList = new List<Foo>(); foreach (Transform item in fooObjects) { Foo f = item.gameObject.GetComponent<Foo>(); if(f != null) { fooList.Add(f); } else { Debug.Log("There are some object which is not FOO"); } } b = new Bar(); } void OnEnable () { foreach (var item in fooList) { item.gameObject.transform.name = "THIS IS FOO"; } fooList.Add(b); // this will throw an error in the debug window. }
お役に立てば幸いです。それでも足りない場合は、ここにコメントしてください。ありがとう