Öffne das Third-Person-Template und du bekommst einen Character-Blueprint und einen GameMode. Dass der GameMode im Hintergrund drei weitere Klassen für dich spawnt und jede davon eine eigene Aufgabe hat, sagt dir niemand. Also landet der Punktestand im Character, der Respawn im Level Blueprint, und beim ersten Tod steht der Punktestand wieder auf null. Dieser Post ist die Übersicht, die das Raten beendet.
Die fünf Klassen in je einem Satz
- GameMode — die Regeln. Wer wo spawnt, wann eine Runde endet, was beim Tod passiert. Einer pro Level, und er existiert nur auf dem Server.
- GameState — die öffentliche Anzeigetafel. Match-Timer, Team-Punkte, die Liste der Spieler. Jeder kann sie lesen.
- PlayerController — der Wille des Spielers. Input, der nicht den Körper betrifft, HUD, Kamera, Menüs. Er überlebt, wenn der Pawn stirbt.
- PlayerState — die Akte des Spielers. Name, Kills, Punkte, Team. Überlebt den Tod ebenfalls, und andere Spieler können sie sehen.
- Pawn / Character — der Körper. Bewegung, Leben, das Mesh, auf das geschossen wird. Verbrauchsmaterial.
Alles Weitere folgt aus einer Frage: Soll das den Tod des Körpers überleben, und muss jemand anderes es sehen?
Wohin gehört der Punktestand?
Punkte pro Spieler gehören in den PlayerState. Team- oder Match-Punkte in den GameState.
Das typische Anfänger-Setup legt eine Variable Points in den Character. Dann stirbt der Character, wird zerstört, ein neuer spawnt, und dessen Points beginnen bei 0. Der PlayerState hat dieses Problem nicht: Er gehört zum Controller, nicht zum Pawn, und ist nach dem Respawn noch da.
CB0
Auslesen geht in jedem Blueprint: Get Player State → Cast To BP_MyPlayerState → Points. (Nenn sie nicht Score: PlayerState hat bereits ein eingebautes Score, das in Blueprints nur lesbar ist, und der Name ist vergeben.) Der GameState ist ein Get Game State entfernt und hält im Player Array bereits die PlayerStates aller Spieler. Genau darüber loopt eine Anzeigetafel.
Wohin gehört die Lebensleiste?
Zwei Antworten, weil es um zwei Dinge geht.
Der Lebenswert liegt im Character. Er ist das Leben des Körpers, und wenn der Körper weg ist, gibt es nichts mehr, das leben könnte. Leben, das den Respawn überstehen soll (etwa ein Max-Health-Upgrade), gehört in die Akte, also in den PlayerState.
Das Lebensleisten-Widget erstellt der PlayerController. Event BeginPlay → Create Widget → Add to Viewport. Im Multiplayer setzt du ein Is Local Controller davor: Der Server hält eine Kopie vom Controller jedes Spielers, und für die alle willst du keine Widgets bauen.
Der Haken: Nach einem Respawn zeigt das Widget noch auf den toten Character. Sobald der neue Pawn possessed ist, gibst du dem Widget die neue Referenz. In einem Singleplayer-Spiel liefert dir Event On Possess im PlayerController den Pawn direkt (es läuft nur auf dem Server, im Multiplayer brauchst du einen Hook auf Client-Seite, das gehört in einen späteren Post über Replication). Wenn das Widget per Event Dispatcher auf Lebensänderungen hört statt per Binding, ist diese Übergabe ein einziger Node.
Wohin gehört der Respawn?
In den GameMode. Tod ist eine Regelfrage: wie lange warten, wo spawnen, ob noch Leben übrig sind.
CB1
Restart Player nimmt den Controller und spawnt einen neuen Default Pawn Class an einem PlayerStart. Zerstör den alten Character vorher. Hat der Controller noch einen Pawn, spawnt Restart Player keinen neuen. Controller und PlayerState bleiben die ganze Zeit unangetastet, und genau deshalb überlebt der Punktestand.
Lass den Character sich nicht selbst respawnen. Er wird gleich zerstört, und ein Blueprint, der sich mitten in der eigenen Logik selbst zerstört, ist eine klassische Quelle für Accessed None-Fehler (siehe häufige Blueprint-Fehler).
Und die GameInstance?
Die GameInstance gehört nicht zu den fünf, und darum geht es. Alles oben wird bei Open Level neu gebaut: GameMode, GameState, Controller, PlayerState, Pawn. Die GameInstance entsteht beim Spielstart und lebt, bis das Spiel geschlossen wird.
Nimm sie für das, was einen Levelwechsel überstehen muss: den gewählten Charakter, den aktiven Speicherslot, Einstellungen. Halt sie klein. Sie ist eine Übergabestelle, kein zweiter GameMode. Was einen Neustart des Spiels überleben muss, gehört in ein SaveGame, nicht hierher (siehe Speichern/Laden).
Singleplayer? Trotzdem wichtig
„Ich mache kein Multiplayer-Spiel“ ist der übliche Grund, das alles zu ignorieren. Zwei Probleme damit. Erstens hat der Punktestand-Bug oben nichts mit Netzwerk zu tun. Zweitens gibt Get Game Mode auf einem Client None zurück. Baust du je Koop ein, bricht jedes Widget, das den Punktestand aus dem GameMode liest. GameState und PlayerState werden an jeden Client repliziert; stell deine Variablen auf Replicated, dann kommen ihre Werte mit. Dafür sind diese beiden Klassen da.
Häufige Fehler
- Deine GameMode-Änderungen bewirken nichts. Schau in die
World Settingsder Map →GameMode Override. Der gewinnt gegen den Default inProject Settings→Maps & Modes, und man vergisst leicht, dass man ihn gesetzt hat. - Du spawnst als falscher Pawn. Entweder stimmt
Default Pawn Classim GameMode nicht, oder im Level steht ein Character mitAuto Possess PlayeraufPlayer 0, der übernimmt, bevor der GameMode deinen spawnt. - Base- und Nicht-Base-Klassen gemischt.
GameModeBasegehört zuGameStateBase,GameModezuGameState. Mischst du sie, werden manche Framework-Funktionen und Events stillschweigend nicht mehr aufgerufen. - Spielzustand im Level Blueprint. Andere Blueprints kommen schlecht ran, und ins nächste Level wandert er auch nicht mit. Regeln gehören in den GameMode.
- Von überall auf den GameMode casten. Ein
Cast Topro Blueprint ist okay. Zehn Blueprints, die alle hart auf den GameMode referenzieren, sind das Abhängigkeitsnetz aus Interfaces statt Casting.
Der 30-Sekunden-Überblick
- GameMode = Regeln und Respawn, nur auf dem Server, einer pro Level.
- GameState = öffentliche Match-Daten wie Timer und Team-Punkte.
- PlayerController = HUD, Menüs, Kamera; überlebt den Tod.
- PlayerState = Punkte und Stats pro Spieler; überlebt den Tod ebenfalls.
- Character = Körper und Leben, wird mit jedem Leben neu erstellt und zerstört.
- GameInstance = die einzige, die
Open Levelübersteht.
Nächsten Sonntag, wenn die Votes mitspielen: Collision-Presets und Channels — Block, Overlap, Ignore und die Checkliste für den Trigger, der nie feuert.
— Marco
Comments
Leave a comment