Pokud bych kódoval v obecném C #, mohu vytvořit seznam, který ukládá pouze určitý typ objektu. Pokud se náhodou pokusím přidat do seznamu něco jiného než tento typ, bude mi to okamžitě řečeno a mohu problém rychle vyřešit.
List<Foo> my_list = new List<Foo>(); my_list.Add(Bar) //Error
Nicméně proto, že jsem pomocí Unity můj skript musí být připojen k GameObject, a to musí být uloženo v seznamu.
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
Chci, aby seznam ukládal pouze „Foo“ „GameObjects (GameObjects s komponentou Foo), nic mi však nebrání v tom, abych omylem uložil jakýkoli typ GameObject, který by mi mohl (a již má) způsobil hodiny škrábání po hlavě, když jsem se snažil tento problém ladit. Existuje způsob, jak podtypovat GameObject tak, aby měl účinek List<GameObject(Foo)> my_list
? Existuje způsob, jak to udělat také s poli?
Odpovědět
Pokud chcete ukládat pouze GameObject
typy, které obsahují konkrétní Component
element, nejjednodušším řešením je použít konkrétní Component
pro typ seznamu.
The b ase Component
třída obsahuje odkaz na „host GameObject
„. Omezením seznamu na konkrétní Component
budete mít stále přístup ke každému příslušnému GameObject
.
níže uvedený skript je příkladem toho, jak byste to spravovali pro obecnou Collider
třídu. Zahrnul jsem metodu speciálně pro přidání prvku, která vrátí bool
k potvrzení, zda byl Collider
skutečně nalezen na GameObject
a metoda speciálně pro přímé získání požadovaného GameObject
na základě indexu v seznamu.
///<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; }
Chcete-li získat bonusové body, můžete z toho udělat základní třídu pomocí generik. Použití generiku, který je založen ve třídě Component
, vám umožňuje za běhu vytvářet instance, které představují jakoukoli komponentu; všechny komponenty dědí z Component
.
Odpovědět
- Vytvořit chování pro každý typ. tj. foo.cs, bar.cs atd.
- Vytvořte požadovaný typ seznamu. tj. List foolist
-
now if you try to add bar instance to foo then it will give an 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. }
Doufám, že to pomůže. Pokud to nestačí, uveďte komentář zde. Díky