Cave: Einstiegshandbuch
Hierarchische Zustandsmaschinen
Lesson 17 of 19 • 25 XP
Keep your place in this quest
Log in or sign up for free to subscribe, follow lesson progress, and access more learning content.
Wenn dein Gameplay wächst, wirst du schließlich Objekte benötigen, die sich je nachdem, was sie gerade tun, unterschiedlich verhalten. Ein Feind kann untätig, patrouillierend, verfolgend, angreifend, betäubt oder tot sein. Eine Tür kann geschlossen, sich öffnend, offen oder verschlossen sein. Ein Bosskampf kann durch mehrere Phasen gehen.
Hier kommen Zustandsmaschinen ins Spiel.

Im Bild oben siehst du den standardmäßigen Feind, den Cave für das neue Projekt erstellt, mit seiner Zustandsmaschine, die rechts geöffnet ist. Wir befinden uns im Zustand "wandern", der innere Zustände hat, wie "zufälliger Selektor" (der Anfangszustand, dargestellt durch die grüne Farbe), "gehe zu zufällig" und "untätig". Du kannst die Übergänge zwischen den Zuständen sehen, die durch die Pfeile dargestellt sind, und dass jeder Zustand seine eigene Logik haben kann, entweder in Python, wie im Bild gezeigt, oder in Logikblöcken.
Eine Zustandsmaschine hilft dir, Verhalten in klare Zustände zu organisieren, anstatt ein großes Skript mit unzusammenhängenden Bedingungen zu schreiben.
In dieser Lektion wirst du lernen:
- Was ein Zustand ist.
- Was ein Übergang ist.
- Warum hierarchische Zustandsmaschinen nützlich sind.
- Wie Caves Zustandsmaschinenkomponente in eine Entität passt.
- Wie
On Enter,On UpdateundOn Exitfunktionieren. - Wie Python und Logikblöcke innerhalb von Zuständen und Übergängen verwendet werden können.
Das Ziel ist, zuerst das mentale Modell zu verstehen. Sobald das Sinn macht, wird der Editor viel einfacher zu bedienen.
Was ist ein Zustand?
Ein Zustand beschreibt, was ein Objekt gerade tut.

Beispielsweise könnte ein Feind diese Zustände haben:
UntätigPatrouilleVerfolgungAngriffTot
Nur einer dieser Zustände sollte normalerweise den Feind gleichzeitig steuern. Wenn der Feind in Patrouille ist, sollte er nicht auch das Angriffsverhalten ausführen. Wenn er in Tot ist, sollte er nicht weiter den Spieler verfolgen.
Das macht das Gameplay leichter nachvollziehbar, da jeder Zustand eine klare Aufgabe hat.
| Zustand | Was er tun könnte |
|---|---|
Untätig |
Stehen und warten. |
Patrouille |
Zwischen Punkten bewegen. |
Verfolgung |
Auf den Spieler zu bewegen. |
Angriff |
Eine Angriffsanimation abspielen und Schaden verursachen. |
Tot |
Die Bewegung deaktivieren und eine Todesanimation abspielen. |
Anstatt zu fragen "Was sollte der Feind in diesem Frame tun?" kannst du fragen "In welchem Zustand ist der Feind gerade?"
Was ist ein Übergang?
Ein Übergang ist die Regel, die die Zustandsmaschine von einem Zustand in einen anderen bewegt.

Beispielsweise:
UntätigzuPatrouille, wenn der Feind anfangen soll sich zu bewegen, nach einem Timer.PatrouillezuVerfolgung, wenn der Spieler entdeckt wird.VerfolgungzuAngriff, wenn der Feind nahe genug ist.AngriffzuVerfolgung, wenn der Angriff abgeschlossen ist.- Jeder Zustand zu
Tot, wenn die Gesundheit null erreicht.
Der Übergang ist nicht das Verhalten selbst. Es ist die Entscheidung, die besagt: "Jetzt sollten wir den Zustand wechseln."
Diese Trennung ist wichtig. Der Angriff-Zustand kann sich auf das Angreifen konzentrieren, während der Übergang entscheidet, wann es Zeit ist, in diesen Zustand ein- oder auszutreten.
Warum hierarchische Zustandsmaschinen helfen
Cave verwendet einen Ansatz der hierarchischen Zustandsmaschine. Dies bedeutet, dass Zustände innerhalb anderer Zustände organisiert werden können. Das ist nützlich, weil viele Verhaltensweisen eine gemeinsame übergeordnete Idee teilen.
Beispielsweise könnte ein Feind so organisiert werden:
Lebendig
Untätig
Patrouille
Verfolgung
Angriff
Tot
Die Zustände Untätig, Patrouille, Verfolgung und Angriff gehören alle zum breiteren Zustand Lebendig. Dies macht die Struktur einfacher zu verstehen und kann helfen, die gleiche Logik an mehreren Stellen zu vermeiden.
Für ein Anfängerprojekt kannst du mit einer einfachen flachen Zustandsmaschine beginnen. Aber wenn dein Gameplay komplexer wird, hilft die Hierarchie, die Logik sauber zu halten.
Die Zustandsmaschinenkomponente
Um eine Zustandsmaschine in einer Szene zu verwenden, benötigt eine Entität eine Zustandsmaschinenkomponente.
Die Komponente verbindet die Entität mit einem Zustandsmaschinen-Asset. Das Asset definiert die Zustände, Übergänge und Logik, während die Komponente diese Logik während des Spiels auf der Entität ausführt.
Das ist ähnlich wie bei anderen Cave-Systemen:
| Asset | Komponente |
|---|---|
| Python-Skript | Python-Komponente führt es aus. |
| Animation | Animationskomponente spielt sie ab. |
| Zustandsmaschine | Zustandsmaschinenkomponente führt sie aus. |
In der Praxis bedeutet das, dass deine Feindentität eine Zustandsmaschinenkomponente haben kann, und diese Komponente kann eine Feind-KI-Zustandsmaschine ausführen.
Ein Zustandsmaschinen-Asset kann Eigenschaften haben, wie du sehen kannst, wenn du zum Eigenschaften-Tab gehst, und diese Eigenschaften können lokal in der Zustandsmaschinenkomponente geändert werden, sodass du modulare Zustandsmaschinen erstellen kannst, die unterschiedliche Einstellungen für verschiedene Arten von Entitäten haben.
Zustandsereignisse
Jeder Zustand kann auf drei wichtige Momente reagieren:
| Ereignis | Wann es läuft | Häufige Verwendung |
|---|---|---|
On Enter |
Wenn der Zustand beginnt. | Timer zurücksetzen, Variablen initialisieren, eine Animation abspielen, ein Ziel auswählen. |
On Update |
Während der Zustand aktiv ist. | Bewegen, Distanzen prüfen, Timer aktualisieren. |
On Exit |
Beim Verlassen des Zustands. | Effekte stoppen, temporäre Werte löschen. |
Beispielsweise könnte ein Angriff-Zustand so funktionieren:
On Enter: die Angriffsanimation abspielen.On Update: auf den Treffmoment oder Animation-Callback warten.On Exit: das Angriffsflag löschen.
Dies lässt jeden Zustand wie ein kleines, eigenständiges Verhalten erscheinen.
Python innerhalb von Zuständen
Zustandsmaschinen können Python für Logik verwenden.
Innerhalb jedes Zustands-Python-Codes bietet Cave nützliche Variablen wie entity und scene, sodass der Zustand die Entität steuern kann, die die Zustandsmaschinenkomponente besitzt.
Beispielsweise könnte ein Zustand einen Sound abspielen, wenn er betreten wird:
cave.playSound("Feind Alarm", volume=0.8)
Oder er könnte eine Eigenschaft von der Entität lesen:
health = entity.properties.get("health", 100)
Das hält die Zustandslogik nahe an dem Verhalten, zu dem sie gehört.
Python innerhalb von Übergängen
Übergänge können ebenfalls Python verwenden. Für die Python-Logik des Übergangs verwendet Cave eine Variable namens result. Wenn result True wird, kann der Übergang stattfinden. Beispielsweise könnte ein Übergang zu einem Zustand Tot die Gesundheit so prüfen:
health = entity.properties.get("health", 100)
result = health <= 0
Ein Übergang von Verfolgung zu Angriff könnte die Distanz prüfen, wenn dein Feindskript oder die Eigenschaften diesen Wert bereitstellen:
player = scene.get("Player")
playerPos = player.getTransform().getWorldPosition()
entityPos = entity.getTransform().getWorldPosition()
distanceToPlayer = (playerPos - entityPos).length()
result = distanceToPlayer < 2.0
Die genauen Daten hängen von deinem Spiel ab, aber die Idee bleibt immer die gleiche: Der Übergang entscheidet, ob es Zeit ist, von einem Zustand in einen anderen zu wechseln.
TIPP: Während eines Übergangs sind alle lokalen Variablen, die im Zustand definiert sind, von dem der Übergang kommt, für dich verfügbar. So konnten wir im vorherigen Beispiel, wo wir die Distanz zwischen der Entität und dem Spieler berechnet haben, die Spieler-Transformation und die Entitäts-Transformation in zwei Variablen im On-Enter-Zustand des Zustands speichern, von dem dieser Übergang kommt, um ein wenig Ressourcen zu sparen, da sie dann zwischengespeichert werden und wir diese Daten nicht mehr in jedem Frame abrufen müssen.
Logikblöcke innerhalb von Zustandsmaschinen
Zustandsmaschinen können auch Logikblöcke verwenden.
Das ist nützlich, wenn du Verhalten visuell anstelle von Python-Code erstellen möchtest. Für viele Gameplay-Aufgaben sind Logikblöcke eine sehr zugängliche Möglichkeit, Ereignisse, Bedingungen und Aktionen zu verbinden.
Sie funktionieren genau gleich wie oben für den Python-Code innerhalb des Zustands oder für einen Übergang erklärt. Die Logikblöcke des Zustands und die Logikblöcke des Übergangs sind bereits mit den Blöcken initialisiert, die du benötigst, um zu beginnen.
Du kannst Python und Logikblöcke je nach Klarheit des Verhaltens, das du baust, mischen. Wenn ein Zustand oder Übergang beide hat, werden beide ausgeführt, und der Übergang findet statt, wenn eines ODER das andere passiert.
Wann man eine Zustandsmaschine verwenden sollte
Verwende eine Zustandsmaschine, wenn ein Objekt klare Verhaltensmodi hat.
Gute Beispiele sind:
- Feind-KI.
- Boss-Phasen.
- Türen und interaktive Objekte.
- Missions- oder Questverlauf.
- Cutscene-Fortschritt.
- Charakterfähigkeitszustände.
Du benötigst möglicherweise keine Zustandsmaschine für winzige Objekte mit nur einer Aktion. Wenn ein Pickup nur einen Ton abspielt und verschwindet, könnte ein kleines Python-Skript oder ein Logikblock-Setup ausreichen.
Was du dir merken solltest
Eine Zustandsmaschine organisiert Gameplay in Zustände und Übergänge.
Zustände beschreiben, was gerade passiert. Übergänge entscheiden, wann zu etwas anderem gewechselt wird. On Enter, On Update und On Exit helfen, jeden Zustand fokussiert und lesbar zu halten.
Für einfaches Verhalten könnte ein Skript ausreichend sein. Für Verhalten mit mehreren Modi macht eine Zustandsmaschine in der Regel die Logik leichter verständlich und einfacher erweiterbar.