So erstellen Sie Listen (und Arrays) in Unity: Nehmen Sie nur GameObjects eines bestimmten “ -Typs ”

Wenn ich in generischem C # codiert habe, kann ich eine Liste erstellen, in der nur ein bestimmter Objekttyp gespeichert ist. Wenn ich versehentlich versuche, der Liste etwas anderes als diesen Typ hinzuzufügen, werde ich umgehend benachrichtigt und kann das Problem schnell beheben.

List<Foo> my_list = new List<Foo>(); my_list.Add(Bar) //Error 

Allerdings, weil ich „m Mit Unity muss mein Skript an ein GameObject angehängt und in der Liste gespeichert werden.

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 

Ich möchte nur, dass die Liste „Foo“ speichert „GameObjects (GameObjects mit der Foo-Komponente), aber nichts hindert mich daran, versehentlich irgendeine Art von GameObject zu speichern, was dazu führen könnte (und bereits), dass ich mir stundenlang am Kopf kratzte, um das Problem zu beheben.

Gibt es eine Möglichkeit, ein GameObject so zu unterteilen, dass es den Effekt von List<GameObject(Foo)> my_list hat? Gibt es eine Möglichkeit, dies auch mit Arrays zu tun?

Antwort

Wenn Sie nur GameObject -Typen speichern möchten, die einen bestimmten Component Element, die einfachste Lösung besteht darin, das spezifische Component für den Listentyp zu verwenden.

Das b Die Klasse ase Component enthält einen Verweis auf die „host GameObject„. Wenn Sie Ihre Liste auf das spezifische Component beschränken, erhalten Sie weiterhin Zugriff auf die jeweiligen GameObject.


Die Das folgende Skript ist ein Beispiel dafür, wie Sie dies für die generische Klasse Collider verwalten würden. Ich habe eine Methode speziell zum Hinzufügen des Elements eingefügt, die eine bool zurückgibt, um zu bestätigen, ob tatsächlich eine Collider auf der GameObject und eine Methode speziell zum direkten Abrufen der erforderlichen GameObject basierend auf einem Index in der Liste.

///<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; } 

Für Bonuspunkte können Sie dies mithilfe von Generika in eine Basisklasse verwandeln. Wenn Sie ein Generikum verwenden, das basiert in der Klasse Component ist, können Sie Instanzen im laufenden Betrieb erstellen, um jede Komponente darzustellen. Alle Komponenten erben von Component.

Antwort

  1. Verhalten für jeder Typ. d.h. foo.cs, bar.cs usw.
  2. Erstellen Sie den gewünschten Listentyp. d. h. List Foolist
  3. Wenn Sie nun versuchen, eine Balkeninstanz zu foo hinzuzufügen, wird ein Fehler ausgegeben. Hinzufügen eines Balkenobjekts zu foo mit Fehler Beschreibung Geben Sie hier die Bildbeschreibung ein Geben Sie hier die Bildbeschreibung ein.

    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. } 

Ich hoffe das hilft. Wenn es nicht genug ist, geben Sie bitte hier einen Kommentar ab. Danke

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.