- Motivation
- Tech-Stack
- Erste Schritte: C#-Basics und Projekt-Setup
- Spielfeld & Assets
- Würfel & Zuglogik
- KI: Anspruchsvoll, aber machbar
- Regeln & Sonderfälle (implementiert/geplant)
- Hürden & Bugs (und wie ich sie angegangen bin)
- Architektur-Notizen
- Eigene Assets & Urheberrecht
- Was ich gelernt habe
- Einstieg & Einrichtung
Ich habe mein erstes Unity-Projekt in C# gestartet: ein Ludo-ähnliches Brettspiel mit KI-Gegnern. Vom Set-up über Prefabs, Pfaddefinition und Würfel-/Zuglogik bis zu einer einfachen KI – inklusive Bugs und Fixes. Es war anstrengend, aber lehrreich, und ich bin motiviert für das nächste Projekt.
Motivation
Ich wollte endlich mit der Game-Entwicklung starten – hands-on statt Tutorials zu bringen. Ein kleines, aber vollständiges Brettspiel mit grundlegender KI. Fokus auf sauberen Code, nachvollziehbare Architektur und das Lösen echter Probleme.
Tech-Stack
- Engine: Unity
- Sprache: C#
- IDE: Jetbrains Rider (persönliche Präferenz gegenüber Visual Studio)
- 3D-Modellierung: Blender
Erste Schritte: C#-Basics und Projekt-Setup
Ich bin mit den Grundlagen gestartet: Variablen, String, int & Co. Danach: Unity installiert, Rider angebunden und das Projekt sauber strukturiert (Scenes, Scripts, Materials, Models).
Spielfeld & Assets
- In Unity eine Plane angelegt und ein Referenzbild als temporäres Board-Layout genutzt
- In Blender eine einfache Spielfigur modelliert und exportiert
- In Unity vier Prefabs (Farben) angelegt und Spawnpunkte im Code definiert
Beispiel: Spawn-Position pro Farbe
using UnityEngine;
public class Spawns : MonoBehaviour
{
public Vector3[] startPositionsGreen = new Vector3[4];
public Vector3[] startPositionsRed = new Vector3[4];
public Vector3[] startPositionsBlue = new Vector3[4];
public Vector3[] startPositionsYellow= new Vector3[4];
}
Pfaddefinition: FieldPath.cs
Für die Spiellogik habe ich den Laufpath als festes Array modelliert. Einmal viel Arbeit, danach wiederverwendbar.
public class FieldPath : MonoBehaviour
{
// 40 Felder als Beispiel – an Boardlayout anpassen
public Vector3[] path = new Vector3[40];
}
Würfel & Zuglogik
Dice (Würfel)
Ein einfacher Würfel, der Werte 1-6 liefert und Events triggert.
using UnityEngine;
using System;
public class Dice : MonoBehaviour
{
public event Action<int> OnRolled;
public int Roll()
{
int value = UnityEngine.Random.Range(1, 7);
OnRolled?.Invoke(value);
return value;
}
}
Turn-/Move-Flow (vereinfacht)
- Spieler würfelt
- Bei 6: Prüfen, ob eine eigene Figur im Haus ist und das Startfeld frei ist -> dann Figur aufs Brett setzen. Vor anderen Züge prüfen, ob im Home-Bereich platzt geschaffen werden muss.
- Normale Züge: Figur entlang FieldPath bewegen
- Begegnungen: Landet eine Figur auf ein Feld mit fremder Figure -> diese zurück ins Haus
- Endbedingung: Sind alle 4 eigenen Figuren im Haus (Zielbereich), ist das Spiel für diesen Spieler beendet.
KI: Anspruchsvoll, aber machbar
Die KI war am schwierigsten. Probleme u.a. bei Spielerzuordnung, Zugreihenfolge und Zugberechtigung. Mehrfaches Recatoring bis es „stabil genug“ lief. Geplat ist, die Heuristiken zu verbessern (z.B. Risiko-/Nutzen-Abwägung, Priorisierung von Schlägen, Einzug ins Haus).
Beispiel: sehr einfache KI-Heuristik
public class SimpleAi : MonoBehaviour
{
public MoveGenerator moveGenerator; // liefert mögliche Moves
public Move ChooseMove(BoardState state, int roll)
{
var moves = moveGenerator.GetLegalMoves(state, roll);
if (moves.Count == 0) return Move.None;
// 1) Kann ich jemanden schlagen? – höchste Priorität
var hit = moves.Find(m => m.WillCapture);
if (hit != null) return hit;
// 2) Kann ich ins Haus einziehen?
var home = moves.Find(m => m.WillEnterHome);
if (home != null) return home;
// 3) Sonst: längster Fortschritt
moves.Sort((a,b) => b.Advance.CompareTo(a.Advance));
return moves[0];
}
}
Regeln & Sonderfälle (implementiert/geplant)
- 6 gewürfelt: nächste Figur darf herausgesetzt werden, sofern Startfeld frei und im Home-Bereich Platz ist
- Rauswerfen: Auf besetztes Feld ziehen -> gegnerische Figur zurück ins Haus
- Haus/Ende: Spieler & KI können das Haus betreten; sind alle 4 Figuren drin -> Spiel für diesen Spieler beendet, sonst KI weiterspielen.
Hürden & Bugs (und wie ich sie angegangen bin)
- Bewegung ungenau
- Fix: Alle Koordinaten einzeln überprüft und angepasst
- KI würfelt vorzeitig (startet, sobald der Spieler eine 6 würfelt; Rot wird herausgesetzt)
- Fix: Update/Turn-Manager so angepasst, dass der Spieler erst nach bis zu drei Würfeln an die KI übergibt; Würfellogik neu aufgesetzt
- Falsche Wurfanzahl (zu oft / nur 2x statt 3x)
- Fix: Zähler und Zustandsautomat (State Machine) eingeführt
- Einzug ins Haus blockiert
- Status: Ursache noch offen; wird priorisiert untersucht
Architektur-Notizen
- State Machine für Phasen: Idle -> Rolling -> Choosing -> Moving -> Resolving -> NextTurn
- Datenstrukturen: BoardState, PieceState, PlayerState zum klaren Trennung von Anzeigen & Logik
- Events (C# event/action) für lose Kopplung zwischen UI, Würfel, Turn-Manager und KI
Eigene Assets & Urheberrecht
Das Board-Design wird auf eigene Grafiken umgestellt, um rechtlich sauber zu bleiben. Platzhalter wurden nur als Referenz verwendet.
Was ich gelernt habe
- Debuggings zuerst strukturieren: kleine Repro-Szene, Logos, Giszmos, Breakpoints
- Klare Zustände verhindern Logik-Chaos (insb. Mehrfachwürfe & Zugübergabe)
- KI iterativ entwickeln: von deterministisch zu heuristisch
- Einmalige Daten (Pfad) lohnen den upfront-Aufwand
Einstieg & Einrichtung
1) Einstieg in C# – die Basis, die alles trägt
Bevor ich Unity geöffnet habe, habe ich mir ein solides Fundament in C# erarbeitet. Ich habe mit Variablen, Datentypen (int, float, bool, string), Operatoren, if/else (for/while), Arrays/Listen und Methoden begonnen. Danach kamen Klassen, Objekte und Vererbung. Besonders wichtig für Unity: Verstehen, wie Referenz- vs. Werttype funktionieren (z.B. Vector3 ist ein struct -> Werttyp) und wie Ereignisse/Delegates für Architektur entkoppeln können.
Unity-spezifisch lernte ich die Lebenszyklen von MonoBehaviour (u.a. Awake, Start, Update, OnEnable / OnDisable) sowie Couroutines (StartCoroutine) für zeitbasierte Abläufe. Das half später enorm bei Würfel-Animationen und Zugsequenzen.
2) Unity einrichten & Rider als IDE
Ich nutze Jetbrains Rider, weil ich mich damit am produktivsten fühle. Ich habe von Anfang an Struktur geschaffen: Ordner für Scenes, Scripts, Prefabs, Materials, Models, Art, ScriptableObjects. Zusätzlich eine .gitignore und Versionskontrolle eingerichtet – so lassen sich Experimente rückgängig machen.
Tipp: Assembly Definitions für größere Projekte nutzen; hier genügte einen Haupt-Assembly. Außerdem habe ich die Play Mode Options auf „Enter Play Mode ohne Domains/Scene Reload“ geprüft (für schnellere Iterationen), aber nur, wenn der Code darauf ausgelegt ist.
Entdecke mehr von DaonWare
Melde dich für ein Abonnement an, um die neuesten Beiträge per E-Mail zu erhalten.