Ein Basisskript für Gegner
Teil des Abschnitts Spielarchitektur in Unity der Unity-Journey von Coddy. Lektion 2 von 50.
Gegner haben den größten Teil ihres Codes gemeinsam: Trefferpunkte, eine Geschwindigkeit, eine Bewegungsart. Dieser Code kann in einer Basisklasse stehen, die von MonoBehaviour abgeleitet ist, und jede Art von Gegner leitet sich davon ab. Dieser Enemy legt seine Trefferpunkte in Start fest und bewegt sich in Update in die Richtung, in die er blickt. Ein Ghost ändert den Start, sodass er sich doppelt so schnell bewegt:
public class Enemy : MonoBehaviour
{
public int maxHp = 3;
public float speed = 2f;
protected int hp;
protected virtual void Start()
{
hp = maxHp;
}
protected virtual void Update()
{
transform.Translate(Vector3.forward * speed * Time.deltaTime);
}
}public class Ghost : Enemy
{
protected override void Start()
{
base.Start();
speed *= 2f;
}
}Ghost erbt die Felder, deshalb zeigt der Inspector bei einem Ghost maxHp und speed an. Außerdem erbt er Update und bewegt sich daher, ohne ein eigenes Update zu haben. hp ist protected: Enemy und seine Unterklassen können es verwenden, andere Skripte nicht.
Unity findet Start und Update anhand ihrer Namen, unabhängig von ihrem Zugriffsmodifizierer, und ruft die Methode der am weitesten abgeleiteten Klasse auf. Wäre Enemys Start eine private void Start()-Methode und würde Ghost eine eigene deklarieren, würde Unity nur die von Ghost aufrufen: Enemys würde nie ausgeführt und hp bliebe ohne Fehlermeldung bei 0. Wenn du die Methoden der Basisklasse als protected virtual deklarierst, ist das ganz normales C#: Die Unterklasse schreibt override, und base.Start() führt den Teil der Basisklasse an der Stelle aus, an der du ihn aufrufst. Lässt du den Aufruf weg, wird der Teil der Basisklasse übersprungen. So ersetzt eine Unterklasse einen Schritt, anstatt ihn zu ergänzen.
Aufgabe
EinfachMonster marschieren auf die Burg zu. In Enemy.cs steht, was sie gemeinsam haben: Start setzt hp auf maxHp und merkt sich spawnPoint, und Update lässt das Monster mit speed entlang der z-Achse marschieren. Der Grunt ist ein einfacher Enemy und funktioniert. Zwei Arten fügen jeweils einen eigenen Schritt hinzu, verlieren dabei aber den Teil von Enemy:
Golem: Sein Start macht den Golem 1.5-mal so groß und protokolliertThe golem wakes up, aber seinhpbleibt 0, weil Unity den Start des Golem ausführt und den von Enemy nie.Wasp: Sein Update schwingt ihn jeweils 1 Einheit auf beide Seiten vonspawnPoint.x, aber er bewegt sich auf der Stelle im Zickzack, weil Unity das Update der Wasp ausführt und das von Enemy nie.
Mach Enemy's Start und Update zu protected virtual und überschreibe sie in Golem und Wasp, sodass jede zuerst den Teil von Enemy und dann ihren eigenen ausführt. Drücke Play und dann Check.
Probier es selbst
using UnityEngine;
// Was alle Monster gemeinsam haben.
public class Enemy : MonoBehaviour
{
public int maxHp = 4;
public float speed = 1.5f;
protected int hp;
protected Vector3 spawnPoint;
void Start()
{
hp = maxHp;
spawnPoint = transform.position;
}
void Update()
{
// Auf die Burg zumarschieren, entlang der z-Achse
transform.position += Vector3.back * speed * Time.deltaTime;
}
}
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