IDamageable
Teil des Abschnitts Spielarchitektur in Unity der Unity-Journey von Coddy. Lektion 6 von 50.
Viele Dinge in einem Spiel können Schaden nehmen, haben aber sonst wenig gemeinsam: Der Spieler hat Lebenspunkte, eine Kiste zerbricht beim ersten Treffer. Eine gemeinsame Basisklasse würde sie in dieselbe Klassenfamilie zwingen. Ein Interface benennt die eine Gemeinsamkeit, und jedes Skript implementiert es auf seine eigene Weise:
public interface IDamageable
{
void TakeDamage(int amount);
}public class PlayerHealth : MonoBehaviour, IDamageable
{
public int hp = 10;
public void TakeDamage(int amount)
{
hp -= amount;
Debug.Log("Ouch! hp: " + hp);
}
}public class Crate : MonoBehaviour, IDamageable
{
public void TakeDamage(int amount)
{
Destroy(gameObject);
}
}Ein Skript hat weiterhin nur eine Basisklasse, MonoBehaviour, und führt die Interfaces danach auf. Das Interface steht in einer eigenen Datei, IDamageable.cs, und leitet sich nicht von MonoBehaviour ab: Es ist keine Komponente und wird nie allein einem Objekt hinzugefügt. Eine Klasse, die es aufführt, muss eine öffentliche Methode TakeDamage(int) haben, sonst wird sie nicht kompiliert.
Was auch immer den Schaden verursacht, fragt nach dem Interface, nicht nach einer Klasse:
// Fireball.cs
void OnCollisionEnter(Collision collision)
{
IDamageable target = collision.gameObject.GetComponent<IDamageable>();
if (target != null)
{
target.TakeDamage(3);
}
Destroy(gameObject);
}Der Feuerball verletzt mit denselben Codezeilen den Spieler und zerbricht Kisten. Wird später eine weitere Art von Ziel hinzugefügt, muss hier nichts geändert werden. Unity zeigt ein Feld vom Typ eines Interfaces nicht im Inspector an. Deshalb speichern Skripte ein GameObject oder eine Komponente und fragen dort nach dem Interface, wie es der Feuerball tut.
Aufgabe
EinfachEin Riese bewacht den Dorfplatz. Die Pfeiltasten bewegen den Riesen (Mover.cs, bereit), und die Leertaste schwingt seinen Hammer: Hammer.cs ruft Slam() auf, das jeden Collider innerhalb von radius findet. Drei Dinge auf dem Platz bekommen einen Treffer, jedes auf seine eigene Weise, und teilen sonst nichts:
Snowman: Jeder Schadenspunkt zieht auf jeder Achse 0.25 von seiner Größe ab (sie beginnt bei 1.5). Bei einer Größe von 0.5 oder weniger schmilzt er: Zerstöre den Schneemann.Bell: Gibt für jeden Schadenspunkt einmalDongaus (bei einem Treffer von 2 wird es zweimal ausgegeben) und addiert die Punkte zurings.Scarecrow: Der erste Treffer kippt ihn um und dreht ihn um 90 Grad um die z-Achse, unabhängig vom Schaden. Spätere Treffer ändern nichts.
IDamageable.cs deklariert das Interface mit einer Methode: void TakeDamage(int amount). Lass Snowman, Bell und Scarecrow es implementieren, jeweils mit einer eigenen Reaktion. Rufe dann in Slam für den IDamageable jedes gefundenen Colliders TakeDamage(power) auf. Collider ohne ein solches Interface, etwa der Boden, werden übersprungen.
Drücke Play, geh zu jedem von ihnen und schwinge den Hammer, dann Check.
Probier es selbst
using UnityEngine;
public class Snowman : MonoBehaviour
{
}
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