Letzte Woche haben wir Dialog aus dem Blueprint-Graph in ein datengetriebenes System geholt. Abilities verdienen dieselbe Behandlung — nur schickt der Standard-Rat Anfänger hier direkt vor die Wand.

Frag irgendwo, wie man Abilities in Unreal baut, und die Antwort ist GAS: das Gameplay Ability System. Es ist wirklich exzellent. Es macht Cooldowns, Kosten, Attribute, Tags, Effekte und Client-Prediction, und Epic shippt Fortnite damit. Es ist aber auch ein Plugin das du in C++ aktivierst, ein Set aus fünf ineinandergreifenden Konzepten, und eine solide Woche deines Lebens, bevor ein Feuerball deine Hand verlässt.

Wenn du solo ein Singleplayer-Spiel baust, ist dieser Tausch meistens falsch. Hier die Version, die es nicht ist.

Was eine Ability wirklich braucht

Runterbrechen. Eine funktionierende Ability hat vier bewegliche Teile:

  1. Darf ich? (Cooldown, Ressource, State)
  2. Bezahlen.
  3. Die Sache tun.
  4. Der UI Bescheid sagen.

Das war's. Alles andere, was GAS dir gibt — Replication, Prediction, stapelnde Effekte, Attribut-Aggregation — ist echter Mehrwert, aber nur wenn du das Problem hast, das es löst.

Die Form: eine Component, N Data Assets

Pack eine AbilityComponent auf deinen Character. Sie besitzt nichts außer einer Liste und einer Map:

CB0

Jede Ability ist ein Primary Data Asset (UAbilityData) — die Wahl aus dem DataTable-vs-DataAsset-Post. Ein Asset pro Ability, um 4 Uhr morgens editierbar ohne einen Graph anzufassen:

CB1

Eine Ability hinzufügen heißt: Rechtsklick, Data Asset erstellen, sechs Felder ausfüllen. Kein neues Blueprint. Keine neue Klasse.

Cooldowns: eine Zahl, kein Timer

Der Instinkt sagt: ein Timer pro Ability. Lass es. Timer sind Objekte, brauchen Cleanup, und überleben kein Save/Load.

Speicher stattdessen einen Zeitstempel:

CB2

Ein Float pro Ability. GetRemaining(Tag) ist Cooldowns[Tag] - Now, geclampt auf null — das ist dein UI-Radial-Fill, gratis, ohne Per-Frame-Tick. Und weil es nur Zahlen in einer Map sind, wandert es ohne Nachdenken in deinen Save.

Eine Falle: GetTimeSeconds ist World-Time, und World-Time pausiert. Wenn du das Spiel pausierst und die Cooldowns sollen weiterlaufen, willst du GetRealTimeSeconds — such dir eins bewusst aus, statt es später zu merken.

States blocken mit Tags

"Kein Zauber während Stun." "Kein Sprint während Cast." Die Boolean-Variante davon verrottet schnell: bIsStunned && !bIsCasting && bHasMana && !bIsInDialogue.

Gib der Component einen Tag-Container. Stun fügt State.Stunned hinzu. Jedes Ability-Data-Asset bekommt einen BlockedByTags-Container. Die Aktivierung stellt eine Frage:

CB3

Neuer State? Neuer Tag. Kein Boolean, kein Anfassen des Aktivierungs-Codes. Das ist die eine Idee, die es sich lohnt komplett aus GAS zu klauen — FGameplayTag kannst du nutzen, ohne das Ability-System-Plugin überhaupt zu aktivieren.

Der UI Bescheid geben

Die Component broadcastet. OnAbilityActivated(Tag), OnCooldownStarted(Tag, Duration), OnAbilityFailed(Tag, Reason). Das HUD bindet einmal und fragt nie wieder — das Dispatcher-Muster, angewendet wo es offensichtlich hingehört. Dein HUD tickt nicht, und es hält keine Referenz auf deinen Character.

Wann GAS wirklich richtig ist

Ehrlich statt dogmatisch. Wechsel zu GAS wenn:

  • Du Multiplayer machst und Abilities sich auf dem Client responsiv anfühlen müssen. Prediction ist wirklich schwer, und GAS hat es schon gelöst.
  • Du stapelnde, zeitgesteuerte, aggregierende Effekte brauchst: fünf Gifte gleichzeitig, jedes mit eigener Dauer und Stärke, alle auf einem Attribut.
  • Du Attribute hast die sich gegenseitig beeinflussen: Rüstung senkt Schaden, Resistenz senkt Rüstung, ein Buff verändert Resistenz.

Wenn du ein Singleplayer-Action-RPG baust, in dem ein Trank 50 Leben gibt und ein Feuerball 3 Sekunden Cooldown hat, ist GAS eine Framework-Steuer ohne Gegenwert.

Häufige Fehler

  • Ein Timer pro Ability. Übersteht kein Save/Load, leakt beim Actor-Destroy, und liefert nichts, was ein Float nicht auch könnte.
  • Cooldown-Logik im Character-Blueprint. Dann braucht sie jede Ability-fähige Klasse. Genau dafür ist die Component da.
  • Montages und VFX hart im Data Asset referenzieren. Dann lädt jede Ability-Animation, wenn der Character lädt. Soft referenzieren und bei Aktivierung async laden.
  • Booleans für States. Sie vermehren sich. Tags nicht.
  • Mit GAS anfangen "weil man das so macht", bei 40% abbrechen und einen Halb-GAS-Hybrid shippen. Das ist schlechter als beide Optionen.
  • Den Cooldown in der UI prüfen statt in der Component. Die UI ist eine Ansicht. Niemals der Türsteher.

30-Sekunden-Recap

  • Vier Teile pro Ability: prüfen, bezahlen, ausführen, melden.
  • Eine AbilityComponent pro Character, ein Primary Data Asset pro Ability.
  • Cooldowns sind eine Map<Tag, float> mit Zeitstempeln — speicherbar, tick-frei, UI-fertig.
  • Gameplay Tags für blockende States; nutzbar ohne das GAS-Plugin.
  • Dispatcher zur UI, kein Polling.
  • Wechsel zu GAS bei Multiplayer-Prediction, stapelnden Effekten oder interagierenden Attributen — vorher nicht.

Nächsten Sonntag: ein Settings-Menü von Grund auf — Auflösung, V-Sync, Audio-Slider, Tastenbelegung, und welche Teile davon UE 5.3 dir schon abnimmt.

— Marco