Si estuviera codificando en C # genérico, puedo crear una lista que solo almacene un cierto tipo de objeto. Si intento agregar accidentalmente algo distinto a ese tipo a la lista, se me informará de inmediato y puedo solucionar el problema rápidamente.
List<Foo> my_list = new List<Foo>(); my_list.Add(Bar) //Error
Sin embargo, porque «m usando Unity, mi script debe adjuntarse a un GameObject, y eso debe almacenarse en la Lista.
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
Solo quiero que la lista almacene «Foo «GameObjects (GameObjects con el componente Foo), sin embargo, no hay nada que me impida almacenar accidentalmente cualquier tipo de GameObject, lo que podría (y ya lo ha hecho) me ha causado horas rascándome la cabeza tratando de depurar el problema.
¿Hay alguna forma de subtipificar un GameObject para que tenga el efecto de List<GameObject(Foo)> my_list
? ¿Hay alguna forma de hacerlo también con matrices?
Respuesta
Si solo desea almacenar GameObject
tipos que contienen un Component
, la solución más sencilla es utilizar el Component
específico para el tipo de lista.
La b La clase ase Component
contiene una referencia al «host GameObject
«. Limitar su lista al Component
específico le dará acceso a cada GameObject
respectivo.
El El siguiente script es un ejemplo de cómo manejaría esto para la clase Collider
genérica. He incluido un método específicamente para agregar el elemento, que devolverá un bool
para confirmar si un Collider
se encontró realmente en el GameObject
, y un método específicamente para recuperar directamente el GameObject
requerido basado en un índice en la lista.
///<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; }
Para obtener puntos de bonificación, puede convertir esto en una clase básica, usando genéricos. El uso de un genérico basado en la clase Component
le permite crear instancias sobre la marcha para representar cualquier componente; todos los componentes heredan de Component
.
Respuesta
- Make Behavior for cada tipo. es decir, foo.cs, bar.cs, etc.
- Cree el tipo de lista que desee. es decir, List foolist
-
ahora, si intenta agregar una instancia de bar a foo, dará un error.
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. }
Espero que eso ayude. Si no es suficiente, haga un comentario aquí. Gracias