Se eu estivesse codificando em C # genérico, posso criar uma lista que armazena apenas um determinado tipo de objeto. Se eu acidentalmente tentar adicionar qualquer coisa diferente desse tipo à lista, serei imediatamente informado e poderei resolver o problema rapidamente.
List<Foo> my_list = new List<Foo>(); my_list.Add(Bar) //Error
No entanto, porque eu “m usando Unity, meu script precisa ser anexado a um GameObject, e isso precisa ser armazenado na 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
Eu só quero que a lista armazene “Foo “GameObjects (GameObjects com o componente Foo), no entanto, não há nada que me impeça de armazenar acidentalmente qualquer tipo de GameObject, o que poderia (e já fez) me fazer ficar horas coçando a cabeça tentando depurar o problema.
Existe uma maneira de criar um subtipo de GameObject para que tenha o efeito de List<GameObject(Foo)> my_list
? Existe uma maneira de fazer isso com matrizes também?
Resposta
Se você deseja armazenar apenas GameObject
tipos que contêm um Component
elemento, a solução mais fácil é usar o Component
específico para o tipo de lista.
O b ase Component
classe contém uma referência ao “host GameObject
“. Limitar sua lista ao Component
específico ainda fornecerá acesso a cada GameObject
respectivo.
O O script abaixo é um exemplo de como você administraria isso para a classe Collider
genérica. Incluí um método específico para adicionar o elemento, que retornará um bool
para confirmar se um Collider
foi realmente encontrado no GameObject
e um método específico para recuperar diretamente o GameObject
necessário com base em um índice na 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 obter pontos de bônus, você pode transformar isso em uma aula básica, usando genéricos. O uso de um genérico baseado na classe Component
permite criar instâncias dinâmicas para representar qualquer componente; todos os componentes herdam de Component
.
Resposta
- Criar comportamento para cada tipo. ou seja, foo.cs, bar.cs etc
- Crie o tipo de lista desejado. ou seja, Lista tola
-
agora, se você tentar adicionar uma instância de bar a foo, ocorrerá um erro.
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 ajude. Se não for suficiente, por favor, comente aqui. Obrigado