Cómo hacer listas (y matrices) en Unity solo toma GameObjects de cierto “ tipo ”

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

  1. Make Behavior for cada tipo. es decir, foo.cs, bar.cs, etc.
  2. Cree el tipo de lista que desee. es decir, List foolist
  3. ahora, si intenta agregar una instancia de bar a foo, dará un error. Añadiendo un objeto bar a foo dando error Descripción ingrese la descripción de la imagen aquí ingrese la descripción de la imagen aquí

    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

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *