Abstrakte Komponenten
Teil des Abschnitts Spielarchitektur in Unity der Unity-Journey von Coddy. Lektion 3 von 64.
Manche Basisklassen beschreiben eine Art von Dingen, die nie für sich allein existiert. Jede Waffe feuert, aber eine Waffe, die weder eine Pistole noch eine Schrotflinte ist, kann nicht feuern. Kennzeichne eine solche Klasse mit abstract und deklariere jeden Schritt, den ihre Unterklassen schreiben müssen, als abstrakte Methode ohne Rumpf:
public abstract class Weapon : MonoBehaviour
{
public int shots;
public void Pull()
{
shots++;
Fire();
}
protected abstract void Fire();
}public class Shotgun : Weapon
{
public GameObject pelletPrefab;
protected override void Fire()
{
for (int i = -1; i <= 1; i++)
{
Instantiate(pelletPrefab, transform.position + transform.right * i * 0.3f, transform.rotation);
}
}
}Eine Unterklasse, die Fire nicht schreibt, lässt sich nicht kompilieren: CS0534, 'Pistol' does not implement inherited abstract member 'Weapon.Fire()'. Unity weigert sich außerdem, ein abstraktes Skript zu einem Objekt hinzuzufügen. Ziehst du Weapon auf ein Objekt, wird Can't add script behaviour 'Weapon'. The script class can't be abstract! angezeigt, da Unity keine Weapon ohne Fire erstellen kann.
Andere Skripte funktionieren weiterhin mit dem Basistyp. GetComponent<Weapon>() gibt die Unterklasse zurück, die sich auf dem Objekt befindet, und Pull() führt das Fire dieser Unterklasse aus:
// Player.cs
private Weapon weapon;
void Start()
{
weapon = GetComponent<Weapon>();
}
void Update()
{
if (Mouse.current.leftButton.wasPressedThisFrame)
{
weapon.Pull();
}
}Tausche die Shotgun-Komponente gegen eine Pistol aus, und das Player-Skript bleibt unverändert.
Aufgabe
EinfachMach Monster abstrakt und lass den Turm jede Art von Monster beschießen.
- Schreibe in
Monsterpublic abstract class Monsterundprotected abstract void React();, ohne Methodenrumpf. - Der Compiler zeigt nun auf
Imp: Fügeprotected override void React()hinzu, dasVector3.forward * 2fzur Position addiert. - Rufe in
Towerinnerhalb der SchleifeZap()fürtarget.GetComponent<Monster>()auf.
Drücke „Spielen“ und die Leertaste: Die Schleime schrumpfen, der Imp springt zurück. Drücke danach „Prüfen“.
Probier es selbst
using UnityEngine;
// Was alle Monster gemeinsam haben.
public class Monster : MonoBehaviour
{
public int hp = 3;
public void Zap()
{
hp--;
if (hp <= 0)
{
Destroy(gameObject);
}
else
{
React();
}
}
// Wie diese Art von Monster auf einen überlebten Stromstoß reagiert.
protected virtual void React()
{
}
}
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