Programming lesson
Finite-State-Maschinen für Prison Dodgeball: KI-Agenten programmieren in Unity
Lerne, wie du eine FSM für Prison Dodgeball in Unity implementierst, um deine KI-Agenten zu steuern und Gegner zuverlässig zu schlagen – mit ballistischer Flugbahnvorhersage und Teamkoordination.
Einführung in die Prison Dodgeball KI mit FSM
In diesem Tutorial erfährst du, wie du eine Finite-State-Maschine (FSM) für das Spiel Prison Dodgeball in Unity erstellst. Deine KI-Agenten sollen selbstständig Entscheidungen treffen: Bälle aufsammeln, werfen, ausweichen und Teamkollegen aus dem Gefängnis retten. Das Besondere: Du kombinierst die FSM mit ballistischer Flugbahnvorhersage aus einer vorherigen Aufgabe, um die Trefferwahrscheinlichkeit zu erhöhen. Egal ob du ein Unity-Anfänger oder erfahrener Entwickler bist – dieses Tutorial führt dich Schritt für Schritt durch den Aufbau einer schlagkräftigen KI.
Was ist eine Finite-State-Maschine?
Eine FSM ist ein Verhaltensmodell, das aus einer begrenzten Anzahl von Zuständen (States) und Übergängen (Transitions) besteht. Stell dir vor, dein Agent durchläuft verschiedene Phasen: „Ball suchen“, „Zum Ball laufen“, „Werfen“, „Ausweichen“ oder „Retten“. Jeder Zustand hat eine Enter()-, Update()- und Exit()-Methode. Solange keine Bedingung für einen Wechsel erfüllt ist, bleibt der Agent im aktuellen Zustand. Sobald ein Ereignis eintritt – z. B. ein gegnerischer Ball fliegt auf ihn zu – wechselt er in den Ausweich-Zustand. Dieses Konzept ist nicht nur in Spielen, sondern auch in der Robotik und KI-Entwicklung weit verbreitet.
Prison Dodgeball verstehen
Das Spielprinzip: Zwei Teams werfen Bälle auf Gegner. Wird ein Spieler getroffen, muss er ins Gefängnis auf der gegnerischen Seite. Ein gefangener Spieler kann nur befreit werden, wenn ein Teamkollege ihm einen Ball zuwirft – ohne Bodenberührung. Der befreite Spieler behält den Ball. Das Team gewinnt, wenn alle Gegner im Gefängnis sind. Es gibt auch Sonderregeln: Ein Ball kann mehrere Gegner treffen, wenn er abprallt; ein Ball, der einen gehaltenen Ball trifft, gilt als Ablenkung. In der Minion-Version gibt es keine Fangmöglichkeit, dafür eine neutrale Zone und eine Zeitbegrenzung. Diese Regeln machen das Spiel zu einer spannenden Herausforderung für die KI-Programmierung.
Voraussetzungen und Projektaufbau
Du benötigst das Unity-Projekt aus dem Kurs, das die Szene PrisonBall enthält. Die Hauptdatei, die du bearbeitest, ist Assets/Scripts/GameAIStudentWork/MinionStateMachine.cs. Diese Klasse erbt von FiniteStateMachine und enthält bereits eine Demo-Implementierung. Du ersetzt die Zustände durch deine eigenen. Zusätzlich reichst du ThrowMethods.cs und ShotSelection.cs ein – auch wenn du die Standard-Implementierung von „Glass Joe“ verwendest. Deine FSM muss gegen „Glass Joe“ und andere KI-Gegner in mindestens zwei Dritteln der Spiele gewinnen.
Schritt 1: Die Grundstruktur der FSM
Beginne mit dem Erstellen der Zustände. Definiere eine Enumeration für die Zustandsnamen, z. B. Idle, SearchBall, MoveToBall, Throw, Dodge, RescueTeammate. Jeder Zustand wird als eigene Klasse implementiert, die von State erbt. In der Start()-Methode der MinionStateMachine erzeugst du die Zustände und fügst sie mit AddState() hinzu. Vergiss nicht, den Startzustand festzulegen, z. B. Idle.
public class IdleState : State
{
public override void Enter() { }
public override void Update() { }
public override void Exit() { }
}Schritt 2: Ballistische Flugbahnvorhersage nutzen
In einer vorherigen Aufgabe (HW5) hast du Algorithmen zur Berechnung von ballistischen Flugbahnen und zur Schussauswahl entwickelt. Diese Methoden kannst du jetzt in deiner FSM verwenden, um die Wurfrichtung und -kraft zu optimieren. Rufe ThrowMethods.CalculateTrajectory() auf, um die Flugbahn zu berechnen, und ShotSelection.SelectBestShot(), um das beste Ziel auszuwählen. Achte darauf, dass du die Parameter wie Abschusswinkel und -geschwindigkeit an die Minion-Eigenschaften anpasst. Du darfst die Methodensignaturen ändern, da der Autograder sie nicht direkt aufruft.
Schritt 3: Zustände implementieren – Idle und Ballsuche
Im Idle-Zustand wartet der Agent, bis ein Ball in der Nähe ist oder ein Gegner bedroht. Nutze die TeamShare-Klasse, um Informationen über Bälle und Teamkollegen zu teilen. Im SearchBall-Zustand sucht der Agent nach dem nächsten freien Ball. Verwende MinionTip, um auf die Position und Geschwindigkeit von Bällen zuzugreifen. Vergiss nicht, auf null zu prüfen – falls keine Daten verfügbar sind, falle in einen sicheren Zustand zurück.
Schritt 4: Bewegen und Werfen
Im MoveToBall-Zustand navigiert der Agent zum Ball. Du kannst Unitys NavMeshAgent verwenden oder einfache Vector3.MoveTowards. Sobald der Agent nah genug ist, wechselt er in den Throw-Zustand. Hier berechnest du mit der ballistischen Vorhersage das Ziel und führst den Wurf aus. Nutze DeferredStateTransition, um nach dem Wurf zurück in Idle zu gehen. Ein Beispiel:
if (ballHeld && target != null)
{
Vector3 throwDirection = ShotSelection.CalculateThrowDirection(target);
agent.ThrowBall(throwDirection);
return new DeferredStateTransition(typeof(IdleState));
}Schritt 5: Ausweichen und Retten
Der Dodge-Zustand wird aktiviert, wenn ein gegnerischer Ball auf den Agenten zufliegt. Du kannst die TeamShare-Daten nutzen, um ankommende Bälle zu erkennen. Der Agent bewegt sich seitlich oder in Deckung. Nach erfolgreichem Ausweichen kehrt er in den vorherigen Zustand zurück. Der RescueTeammate-Zustand ist komplexer: Der Agent muss zu einem gefangenen Teamkollegen gehen und ihm einen Ball zuwerfen. Achte darauf, dass der Ball nicht den Boden berührt. Verwende die ballistische Vorhersage, um den Wurf genau zu platzieren.
Schritt 6: Teamkoordination mit TeamShare
Die TeamShare-Klasse funktioniert wie eine Blackboard-Architektur. Du kannst dort speichern, welcher Agent welchen Ball verfolgt, um doppelte Arbeit zu vermeiden. Erweitere die Klasse um eine Liste von Aufgaben, z. B. „Ball jagen“, „Gegner angreifen“ oder „Retten“. Jeder Agent prüft vor dem Handeln, ob die Aufgabe bereits vergeben ist. So agiert das Team effizienter und vermeidet chaotisches Verhalten. Denke daran, immer auf null zu prüfen und einen Fallback zu haben.
Schritt 7: Fehlerbehandlung und robustes Verhalten
Deine KI soll nicht einfrieren oder unvorhersehbar agieren. Implementiere Timeouts: Wenn ein Agent zu lange in einem Zustand bleibt, wechsle in einen Standardzustand. Vermeide Endlosschleifen, indem du Zustandsübergänge begrenzt. Teste deine FSM mit verschiedenen Teamgrößen (1-5) und Ballanzahlen (1-4). Stelle sicher, dass sie gegen „Glass Joe“ in 2/3 der Spiele gewinnt. Nutze den Unity-Editor, um das Verhalten in Echtzeit zu beobachten und zu optimieren.
Trend-Analogie: KI wie in modernen Battle-Royale-Spielen
Denk an die KI in Spielen wie Fortnite oder PUBG: Bots entscheiden selbstständig, wann sie looten, kämpfen oder fliehen. Deine Prison Dodgeball KI funktioniert ähnlich – sie analysiert die Umgebung, trifft Entscheidungen basierend auf Zuständen und passt sich an. Das Konzept der FSM wird auch in der autonomen Fahrzeugsteuerung oder in Chatbots eingesetzt. Indem du dieses Projekt meisterst, erwirbst du Fähigkeiten, die in der Spieleentwicklung und KI-Forschung gefragt sind.
Optimierung und Testen
Nach der Implementierung ist Testen entscheidend. Spiele viele Runden gegen verschiedene Gegner. Nutze die Debugging-Tools von Unity, um Zustandswechsel zu verfolgen. Überprüfe, ob die ballistische Vorhersage korrekt arbeitet. Wenn deine KI verliert, analysiere die Schwachstellen: Liegt es an der Schussgenauigkeit, am Ausweichen oder an der Teamkoordination? Passe die Parameter an. Denke daran: Deine FSM muss auch gegen unbekannte Gegner bestehen – also baue sie flexibel und robust.
Zusammenfassung
In diesem Tutorial hast du gelernt, wie du eine Finite-State-Maschine für Prison Dodgeball in Unity implementierst. Du hast die Grundstruktur der FSM kennengelernt, ballistische Vorhersage integriert und Teamkoordination mit TeamShare umgesetzt. Mit diesen Werkzeugen kannst du eine KI entwickeln, die zuverlässig Gegner besiegt. Viel Erfolg bei deiner Implementierung – und denk dran: Übung macht den Meister!