VirtualJoystick in Godot 4.7: Endlich ein nativer Touchscreen-Stick
Source: Dev.to
Überblick
Bis vor kurzem hattest du in Godot zwei Optionen, wenn du einen virtuellen Joystick auf dem Smartphone wolltest:
- Plugin installieren
- Selbst bauen
Beides hatte den gleichen Effekt: Edge‑Cases mit Multitouch, manuelles Resolution‑Scaling und am Ende eine Klasse mit ~200 Zeilen, die du bei jedem Engine‑Update neu testen musstest.
Mit Godot 4.7 beta 1 (24. April 2026) ist das vorbei. Der neue VirtualJoystick‑Knoten ist Teil der Engine, hat drei Modi und fügt sich sauber ins Action‑Mapping‑System ein.
Warum TouchScreenButton nicht ausreicht
Godot hatte bereits den Knoten TouchScreenButton für mobile Steuerungen. Das Problem:
- Er erbt von Node2D → kann keine Anchors verwenden.
- Damit lässt er sich nicht relativ zum Bildschirmrand positionieren.
Der Reviewer Calinou formulierte es im Pull‑Request knapp:
“TouchScreenButton inherits from Node2D, which means it can’t make use of anchors.”
Für ein Element, das auf jedem Display‑Format ordentlich aussehen soll, ist das ein Show‑Stopper.
Original Proposal:
“When creating a mobile game, you often need a virtual joystick so the player can move around. However, this is nontrivial to implement correctly.”
Resultat: Jedes mobile Godot‑Projekt hatte entweder eine Asset‑Library‑Abhängigkeit oder eine selbst geschriebene Joystick‑Klasse, die in vielen Fällen Edge‑Cases falsch handhabte (Multitouch‑Tracking, Resolution‑Scaling, Verhalten beim Verlassen des Sticks).
VirtualJoystick – die native Lösung
- Erbt von
Control→ Anchors,size_flags,theme_overrideund alles, was Control‑Nodes können, funktionieren. - Prozedurale Darstellung (keine Bitmap) → scharf bei 1080 p, 4 K‑Tablet usw.
- Theme‑Properties passen Look (Hintergrund, Knopf, Farben) an.
Signale (im Editor verbindbar)
| Signal | Beschreibung |
|---|---|
tapped | Losgelassen, ohne dass der Stick bewegt wurde |
released | Der Finger hat den Bildschirm verlassen |
flicked | Der Stick wurde aus der Deadzone heraus bewegt |
flick_canceled | Ein Flick wurde initiiert, aber wieder zurückgezogen |
Hinweis: Das
tapped‑Signal ermöglicht die Nutzung des Joysticks als Action‑Button, wenn der Spieler nur kurz tippt.
Die drei Modi
| Modus | Stick‑Position | Bewegung über Bounds | Typischer Einsatz |
|---|---|---|---|
| JOYSTICK_FIXED | Unverändert (wo du ihn platzierst) | Nein | Klassische UI, Action‑Spiele mit fester UI |
| JOYSTICK_DYNAMIC | Springt zur Berührung | Nein | Mobile‑Ports von Joypad‑Spielen (mehr Komfort) |
| JOYSTICK_FOLLOWING | Springt zur Berührung, folgt Finger über Bounding‑Box hinaus | Ja | Twin‑Stick‑Shooter, große Displays |
Kurzbeschreibung der Modi
- JOYSTICK_FIXED – Der Stick bleibt an seiner Position. Nichts passiert, wenn der Spieler nicht direkt darauf tippt.
- JOYSTICK_DYNAMIC – Tippt der Spieler in die Größe‑Region des Controls, springt der Knopf zur Berührungsposition. Der Stick selbst bewegt sich nicht weiter.
- JOYSTICK_FOLLOWING – Wie DYNAMIC, aber der Stick folgt dem Finger auch außerhalb der ursprünglichen Bounding‑Box. Beim Loslassen springt er zurück.
Verwendung im Editor
-
Node‑Aufbau
- Lege
VirtualJoystickals Kind eines CanvasLayer an, damit er nicht mit der Welt‑Kamera scrollt.
- Lege
-
Action‑Mapping
- Mappe die Richtungen auf Input‑Actions (z. B.
move_left,move_right,move_up,move_down).
- Mappe die Richtungen auf Input‑Actions (z. B.
Code‑Beispiel
extends CharacterBody2D
@export var move_speed: float = 200.0
func _physics_process(_delta: float) -> void:
var input_dir := Input.get_vector(
"move_left",
"move_right",
"move_up",
"move_down"
)
velocity = input_dir * move_speed
move_and_slide()
- Im VirtualJoystick‑Inspector trägst du
move_left,move_right,move_upundmove_downals Action‑Properties ein. - Der Knoten triggert die Actions automatisch mit einer Stärke zwischen 0.0 und 1.0.
- Dein Spiel‑Code muss nichts vom Joystick wissen – plattform‑agnostisch, funktioniert auch mit Gamepad oder Tastatur.
Was bewusst weggelassen wurde
| Feature | Grund |
|---|---|
| Deadzone‑Konfiguration im Knoten | Die Deadzone gehört zur Input‑Action (Project Settings → Input Map). Doppelte Konfiguration wäre fehleranfällig. |
| Clamp‑Zone (Zone, in der der Stick „gefangen“ bleibt) | War im Original‑Proposal optional, wurde aber in der finalen Version entfernt. |
Diese Entscheidungen sind Design‑Entscheidungen, keine Lücken. Wenn du sie brauchst, kannst du den Knoten erben und selbst hinzufügen – im Standard‑Workflow ist das nicht nötig.
Warum das wichtig ist
- Viele Entwickler besitzen bereits eigene
VirtualJoystick.gd‑Klassen oder nutzen Plugins aus der Asset‑Library (100 – 300 Zeilen Code, je nach Edge‑Case‑Abdeckung). - Die Asset‑Library listet aktuell ~20 konkurrierende Joystick‑Plugins.
Der native Knoten eliminiert:
- Die Notwendigkeit, ein Plugin zu wählen und zu warten.
- Das Risiko, dass ein Plugin nach einem Engine‑Update nicht mehr funktioniert.
Der Knoten wird vom Engine‑Team gewartet und verschwindet beim nächsten Update nicht.
Fazit
Wenn dein Spiel auf Touchscreen abzielt, ist VirtualJoystick die empfohlene Lösung. Sie spart Zeit, reduziert Bugs und ist zukunftssicher.
Mobile Games erzielten 2024 in Deutschland Rekord‑Umsätze von 3 Milliarden € – ein starkes Signal, dass Touch‑Optimierung weiterhin entscheidend bleibt.
Marktüberblick & Entwicklung von Mobile‑Gaming in Deutschland
-
Umsatzwachstum:
„Euro, 63 % mehr als 2019.“ Das Smartphone ist seit Jahren die meistgenutzte Gaming‑Plattform hierzulande. -
Entwicklungs‑Strategie vieler Indie‑Studios:
Hybrid‑Ansatz – zuerst ein Desktop‑Release, anschließend ein Mobile‑Port. In diesem Mobile‑Port‑Schritt war die Touchscreen‑Steuerung bisher ein Tag Handarbeit. -
Aktueller Stand von Version 4.7:
- befindet sich in der Beta‑Phase
- stabiler Release wird in etwa zwei Monaten erwartet
-
Tipp für Entwickler*innen:
Wenn du an einem Mobile‑Spiel arbeitest, lohnt sich der frühe Sprung, um den Joystick vor dem Launch zu testen.
Klein, aber konkret.