Hur man skapar listor (och arrays) i enhet tar endast GameObjects av en viss “ typ ”

Om jag kodade i generisk C # kan jag skapa en lista som bara lagrar en viss typ av objekt. Om jag av misstag försöker lägga till något annat än den typen i listan får jag omedelbart besked och kan åtgärda problemet snabbt.

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

Men eftersom jag ”m med hjälp av Unity måste mitt skript bifogas ett GameObject, och det måste lagras i listan.

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 

Jag vill bara att listan ska lagra ”Foo ”GameObjects (GameObjects med Foo-komponenten), men det finns inget som hindrar mig från att oavsiktligt lagra någon typ av GameObject, vilket kan (och redan har) orsakat att jag klättrade i timmar och försök att felsöka problemet.

Finns det ett sätt att undertypa ett GameObject så att det får effekten av List<GameObject(Foo)> my_list? Finns det ett sätt att göra det med arrays också?

Svara

Om du bara vill lagra GameObject typer som innehåller en specifik Component element, den enklaste lösningen är att använda den specifika Component för listtypen.

B ase Component klass innehåller en hänvisning till ”värd GameObject”. Att begränsa din lista till det specifika Component ger dig fortfarande tillgång till respektive GameObject.


nedanstående skript är ett exempel på hur du skulle hantera detta för den generiska Collider -klassen. Jag har inkluderat en metod specifikt för att lägga till elementet, som returnerar en bool för att bekräfta om en Collider faktiskt hittades på GameObject, och en metod specifikt för att direkt hämta den nödvändiga GameObject baserat på ett index i listan.

///<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 bonuspoäng kan du förvandla detta till en grundklass med generik. Med hjälp av en generik som är baserad i klassen Component kan du skapa förekomster i farten för att representera någon komponent; alla komponenter ärver från Component.

Svar

  1. Gör beteende för varje typ. dvs foo.cs, bar.cs etc
  2. Skapa önskad typ av lista. dvs lista idioter
  3. nu om du försöker lägga till barinstans till foo kommer det att ge ett fel. Lägga till stapelobjekt till foo som ger fel Beskrivning ange bildbeskrivning här ange bildbeskrivning här

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

Jag hoppas att det hjälper. Om det inte räcker, ge en kommentar här. Tack

Lämna ett svar

Din e-postadress kommer inte publiceras. Obligatoriska fält är märkta *