VirtualJoystick in Godot 4.7: Endlich ein nativer Touchscreen-Stick

Published: (May 1, 2026 at 01:41 PM EDT)
5 min read
Source: Dev.to

Source: Dev.to

Überblick

Bis vor kurzem hattest du in Godot zwei Optionen, wenn du einen virtuellen Joystick auf dem Smartphone wolltest:

  1. Plugin installieren
  2. 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_override und 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)

SignalBeschreibung
tappedLosgelassen, ohne dass der Stick bewegt wurde
releasedDer Finger hat den Bildschirm verlassen
flickedDer Stick wurde aus der Deadzone heraus bewegt
flick_canceledEin 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

ModusStick‑PositionBewegung über BoundsTypischer Einsatz
JOYSTICK_FIXEDUnverändert (wo du ihn platzierst)NeinKlassische UI, Action‑Spiele mit fester UI
JOYSTICK_DYNAMICSpringt zur BerührungNeinMobile‑Ports von Joypad‑Spielen (mehr Komfort)
JOYSTICK_FOLLOWINGSpringt zur Berührung, folgt Finger über Bounding‑Box hinausJaTwin‑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

  1. Node‑Aufbau

    • Lege VirtualJoystick als Kind eines CanvasLayer an, damit er nicht mit der Welt‑Kamera scrollt.
  2. Action‑Mapping

    • Mappe die Richtungen auf Input‑Actions (z. B. move_left, move_right, move_up, move_down).

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_up und move_down als 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

FeatureGrund
Deadzone‑Konfiguration im KnotenDie 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.

0 views
Back to Blog

Related posts

Read more »

Pygame Snake, Pt. 4

Introduction In Parts 1, 2, & 3 we assembled everything except the actual game logic. Now we’ll add the snake mechanics. Replace the single dot with a snake li...