Como fazer listas (e matrizes) no Unity aceita apenas GameObjects de um determinado “ tipo ”

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

  1. Criar comportamento para cada tipo. ou seja, foo.cs, bar.cs etc
  2. Crie o tipo de lista desejado. ou seja, Lista tola
  3. agora, se você tentar adicionar uma instância de bar a foo, ocorrerá um erro. Adicionar objeto bar a foo dando erro Descrição insira a descrição da imagem aqui insira a descrição da imagem aqui

    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

Deixe uma resposta

O seu endereço de email não será publicado. Campos obrigatórios marcados com *