Abstrakte Komponenten
Teil des Abschnitts Spielarchitektur in Unity der Unity-Journey von Coddy. Lektion 3 von 50.
Manche Basisklassen beschreiben eine Art von Objekt, die niemals 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 implementieren 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 implementiert, lässt sich nicht kompilieren: CS0534, 'Pistol' does not implement inherited abstract member 'Weapon.Fire()'. Unity weigert sich außerdem, ein abstraktes Skript einem Objekt hinzuzufügen. Ziehst du Weapon auf ein Objekt, erscheint die Meldung Can't add script behaviour 'Weapon'. The script class can't be abstract!, da Unity keine Weapon ohne Fire erstellen könnte.
Andere Skripte funktionieren weiterhin mit dem Basistyp. GetComponent<Weapon>() gibt die Unterklasse zurück, die sich auf dem Objekt befindet, und Pull() führt deren Fire 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
EinfachDer Turm des Zauberers versetzt die Monster auf dem Feld mit einem Zap. Monster.cs enthält, was alle Monster gemeinsam haben: hp (3) und Zap(), wodurch 1 hp abgezogen wird, das Monster bei 0 zerstört wird und andernfalls React() aufgerufen wird. Slime.cs reagiert, indem es schrumpft. Imp.cs hat keine Reaktion, und Monster gibt ihm ein leeres React, sodass dir nicht auffällt, dass es fehlt.
- Mach Monster abstrakt und React zu einer abstrakten Methode, damit ein Monster, das nicht angibt, wie es reagiert, nicht kompiliert. Der Compiler verweist dann auf Imp.
- Schreib React für Imp: Es springt 2 Einheiten zurück, weg vom Turm (entlang +z).
- Hol dir in Tower.cs, wenn die Leertaste gedrückt wird, die Monster-Komponente jedes Objekts mit dem Tag Monster, egal um welche Art es sich handelt, und ruf
Zap()auf.
Drück Play und zap die Monster, dann Check.
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 Stromschlag reagiert, den sie überlebt.
protected virtual void React()
{
}
}
Diese Lektion enthält ein kurzes Quiz. Starte die Lektion, um es zu beantworten und deinen Fortschritt zu speichern.
Alle Lektionen in Spielarchitektur in Unity
1Komponenten statt Hierarchien
Kleine KomponentenEin Basisskript für GegnerAbstrakte KomponentenKomponenten im ZusammenspielRückblick: Modularer Geschützturm4Serialisierte Daten
Serialisierbare KlassenListen im InspectorEnums im InspectorRückblick: Loot-Tabelle7Zustandsautomaten
Zustände als KlassenEin ZustandsautomatÜbergängeGegner-KIWiederholung: Türzustände10Projekt: Arena-Überlebenskampf
Der HeldGegnertypen2Interfaces in Unity
IDamageableInterfaces und TryGetComponentGetComponentsRückblick: Interaktionstaste5ScriptableObjects
Daten-AssetsWaffenwerteGemeinsame EinstellungenWellen als DatenRückblick: Item-Datenbank8Wiederverwendbarer Code
ErweiterungsmethodenEin generisches SingletonGenerische HilfsmethodenRückblick: FindNearest