GetComponents
Teil des Abschnitts Spielarchitektur in Unity der Unity-Journey von Coddy. Lektion 9 von 64.
GetComponent<T>() gibt den ersten Treffer zurück. GetComponents<T>() gibt alle Treffer auf dem Objekt als Array zurück, und GetComponentsInChildren<T>() alle Treffer auf dem Objekt und allem darunter. Wenn T ein Interface ist, sammelt ein einziger Aufruf alle Komponenten, die etwas tun können, unabhängig von ihrer Klasse. Hier sind die Maschinen einer Fabrik untergeordnete Objekte des Factory-Objekts, und jede Komponente, die mit Strom betrieben wird, implementiert IPowered:
public interface IPowered
{
void SetPower(bool on);
}public class Generator : MonoBehaviour
{
public GameObject factory;
public void Switch(bool on)
{
IPowered[] parts = factory.GetComponentsInChildren<IPowered>();
foreach (IPowered part in parts)
{
part.SetPower(on);
}
Debug.Log(parts.Length + " parts powered");
}
}Eine Lamp schaltet ihr Light ein, ein Fan beginnt sich zu drehen, ein Conveyor setzt sich in Bewegung – jeweils in der eigenen SetPower-Methode. Eine Maschine mit einer Lamp und einem Fan auf einem Objekt zählt doppelt, da jede Komponente ein eigener Treffer ist. Der Generator benennt sie nie, daher wird eine Siren, die IPowered implementiert und später unter Factory hinzugefügt wird, beim nächsten Aufruf von Switch eingeschaltet.
GetComponentsInChildren berücksichtigt das Objekt, auf dem du die Methode aufrufst, und überspringt inaktive untergeordnete Objekte, sofern du nicht true übergibst: GetComponentsInChildren<IPowered>(true). GetComponents betrachtet nur das eine Objekt. Das eignet sich für Komponenten, die nebeneinander sitzen, etwa ein Licht und ein Summer an einer Tür.
Aufgabe
EinfachLass jeden Teil des Roboters einen Treffer anzeigen.
- Erkläre in
IHitReaction.cspublic interface IHitReactionmitvoid React(int damage);. - Lass
Flash,RecoilundSparksdie Schnittstelle implementieren: Benenne jede Methode inpublic void React(int damage)um. Recoilbewegt sich um0.5f * damagezurück;SparksschleudertdamageFunken.- Rufe in
TakeDamagefür jedesGetComponentsInChildren<IHitReaction>()React(amount)auf und protokolliere anschließendReactions: 3(ihre Anzahl).
Drücke „Spielen“, drücke die Leertaste und klicke dann. Drücke anschließend „Prüfen“.
Probier es selbst
using UnityEngine;
public class Health : MonoBehaviour
{
public int hp = 10;
public void TakeDamage(int amount)
{
hp -= amount;
GetComponentInChildren<Flash>().Show();
}
}
Alle Lektionen in Spielarchitektur in Unity
1Komponenten statt Hierarchien
Kleine KomponentenEin Basis-GegnerskriptAbstrakte KomponentenZusammenwirkende KomponentenRückblick: Modulares GeschützRückblick: Zwillingskanone4Serialisierte Daten
Serialisierbare KlassenListen im InspectorEnums im InspectorRückblick: Loot-TabelleRückblick: Beute auswürfeln2Schnittstellen in Unity
IDamageableSchnittstellen und TryGetComponentGetComponentsZusammenfassung: InteraktionstasteZusammenfassung: Nächstes in Reichweite5ScriptableObjects
Daten-AssetsWaffenwerteGemeinsame EinstellungenDen Wind speichernWellen als DatenRückblick: Item-DatenbankRückblick: Im Shop einkaufen8Wiederverwendbarer Code
ErweiterungsmethodenEin generisches SingletonGenerische HilfsmethodenRückblick: FindNearestÜbe selbstständig: Unity-Playground