Come creare elenchi (e array) in Unity, accetta solo GameObject di un determinato “ tipo ”

Se stessi codificando in C # generico posso creare un elenco che memorizza solo un certo tipo di oggetto. Se provo accidentalmente ad aggiungere qualcosa di diverso da quel tipo allelenco, mi verrà prontamente informato e posso risolvere il problema rapidamente.

List<Foo> my_list = new List<Foo>(); my_list.Add(Bar) //Error 

Tuttavia, perché “m utilizzando Unity il mio script deve essere allegato a un GameObject e questo deve essere memorizzato nellelenco.

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 

Voglio che lelenco memorizzi solo “Foo “GameObjects (GameObjects with the Foo component), tuttavia non cè nulla che mi impedisca di memorizzare accidentalmente qualsiasi tipo di GameObject, il che potrebbe (e ha già) causato ore e ore a grattarmi la testa cercando di risolvere il problema.

Cè un modo per sottotipizzare un GameObject in modo che abbia leffetto di List<GameObject(Foo)> my_list? Cè un modo per farlo anche con gli array?

Rispondi

Se desideri memorizzare solo GameObject tipi che contengono uno specifico Component, la soluzione più semplice è utilizzare lelemento Component specifico per il tipo di elenco.

Il b La classe ase Component contiene un riferimento a “host GameObject“. Limitare lelenco allo specifico Component ti darà comunque accesso a ciascun rispettivo GameObject.


Il lo script sottostante è un esempio di come gestireste questo per la classe generica Collider. Ho incluso un metodo specifico per aggiungere lelemento, che restituirà un bool per confermare se un Collider è stato effettivamente trovato su GameObject e un metodo specifico per recuperare direttamente il GameObject richiesto basato su un indice nellelenco.

///<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; } 

Per i punti bonus, potresti trasformarlo in una lezione di base, usando i generici. Lutilizzo di un generico basato nella classe Component consente di creare istanze al volo per rappresentare qualsiasi componente; tutti i componenti ereditano da Component.

Risposta

  1. Comportamento per ogni tipo. Ad esempio foo.cs, bar.cs ecc
  2. Crea il tipo di elenco desiderato. cioè List foolist
  3. ora se provi ad aggiungere listanza di bar a foo, allora darà un errore. Aggiunta di un oggetto barra a foo che dà errore Descrizione inserisci qui la descrizione dellimmagine inserisci qui la descrizione dellimmagine

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

Spero che questo aiuti. Se non è abbastanza, per favore lascia un commento qui. Grazie

Lascia un commento

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *