Unityでリスト(および配列)を作成する方法は、特定の“タイプ”

汎用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をサブタイプ化する方法はありますか?配列でもそれを行う方法はありますか?

回答

特定のComponentGameObjectタイプのみを保存する場合>要素の場合、最も簡単な解決策は、リストタイプに特定の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から継承します。

回答

  1. 各タイプ。つまり、foo.cs、bar.csなど
  2. 目的のタイプのリストを作成します。つまり、リストfoolist
  3. fooにbarインスタンスを追加しようとすると、エラーが発生します。 fooにバーオブジェクトを追加するとエラーが発生します 説明 ここに画像の説明を入力 ここに画像の説明を入力

    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. } 

お役に立てば幸いです。それでも足りない場合は、ここにコメントしてください。ありがとう

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です