Cum se fac liste (și matrice) în Unity, se iau numai GameObjects de un anumit tip “ ”

Dacă aș codifica în C # generic, pot crea o listă care stochează doar un anumit tip de obiect. Dacă încerc din greșeală să adaug ceva în afară de acel tip pe listă, mi se va spune cu promptitudine și pot rezolva problema rapid.

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

Cu toate acestea, pentru că „m folosind Unity, scriptul meu trebuie atașat la un GameObject și acesta trebuie stocat în Listă.

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 

Vreau doar ca lista să stocheze „Foo „GameObjects (GameObjects cu componenta Foo), cu toate acestea, nu există nimic care să mă împiedice să stochez accidental orice tip de GameObject, ceea ce ar putea (și deja mi-a provocat) să mă zgâri în cap încercând să depanez problema.

Există o modalitate de a subtipa un GameObject astfel încât să aibă efectul List<GameObject(Foo)> my_list? Există o modalitate de a o face și cu tablouri?

Răspunde

Dacă vrei să stochezi doar GameObject tipuri care conțin un Component element, cea mai ușoară soluție este să folosiți Component specific pentru tipul listei.

Clasa ase Component conține o referință la „gazdă GameObject„. Limitarea listei la Component vă va oferi în continuare acces la fiecare GameObject respectiv.


scriptul de mai jos este un exemplu al modului în care ați gestiona acest lucru pentru clasa generică Collider. Am inclus o metodă specifică pentru adăugarea elementului, care va returna un bool pentru a confirma dacă un Collider a fost de fapt găsit pe GameObject și o metodă specifică pentru recuperarea directă a GameObject necesară pe baza unui index din listă.

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

Pentru punctele bonus, puteți transforma acest lucru într-o clasă de bază, folosind generice. Utilizarea unui generic bazat în clasa Component vă permite să creați instanțe din mers pentru a reprezenta orice componentă; toate componentele moștenesc de la Component.

Răspunde

  1. Fă Comportament pentru fiecare tip. adică foo.cs, bar.cs etc
  2. Creați tipul de listă dorit. Adică List prostit
  3. acum, dacă încercați să adăugați o instanță de bare la foo, atunci va da o eroare. Adăugarea obiectului barei la foo dând eroare Descriere introduceți descrierea imaginii aici introduceți descrierea imaginii aici

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

Sper că te va ajuta. Dacă nu este suficient, vă rugăm să dați un comentariu aici. Mulțumesc

Lasă un răspuns

Adresa ta de email nu va fi publicată. Câmpurile obligatorii sunt marcate cu *