Up to date

This page is up to date for Godot 4.2. If you still find outdated information, please open an issue.

Controller, Gamepads und Joysticks

Godot unterstützt Hunderte von Controller-Modellen dank der von der Community bereitgestellten SDL Game Controller Database.

Controller werden auf Windows, macOS, Linux, Android, iOS und HTML5 unterstützt.

Beachten Sie, dass speziellere Geräte wie Lenkräder, Ruderpedale und HOTAS weniger getestet sind und möglicherweise nicht immer wie erwartet funktionieren. Das Aufheben des Force-Feedbacks für diese Geräte ist ebenfalls noch nicht implementiert. Wenn Sie Zugang zu einem dieser Geräte haben, zögern Sie nicht, Bugs auf GitHub zu melden.

In dieser Anleitung lernen Sie:

  • Wie Sie Ihre Eingabelogik schreiben, um sowohl Tastatur- als auch Controllereingaben zu unterstützen.

  • Wie sich Controller anders verhalten können als Tastatur/Maus-Eingaben

  • Probleme mit Controllern in Godot beheben.

Unterstützung der Universaleingabe

Dank des Godot-Eingabeaktionssystems ist es möglich, sowohl Tastatur- als auch Controllereingaben zu unterstützen, ohne separate Codepfade schreiben zu müssen. Anstatt Tasten oder Controllertasten in Ihren Skripten fest zu kodieren, sollten Sie in den Projekteinstellungen Eingabeaktionen erstellen, die sich dann auf bestimmte Tasten- und Controllereingaben beziehen.

Eingabeaktionen werden auf der Seite Verwendung von InputEvent ausführlich erklärt.

Bemerkung

Im Gegensatz zur Tastatureingabe erfordert die Unterstützung von Maus- und Controllereingaben für eine Aktion (z. B. das Umsehen in einem Ego-Spiel) unterschiedliche Codepfade, da diese getrennt behandelt werden müssen.

Welche Input-Singleton-Methode sollte ich verwenden?

Es gibt 3 Möglichkeiten, analoge Eingaben zu erhalten:

  • Wenn Sie zwei Achsen haben (z.B. Joystick- oder WASD-Bewegung) und beide Achsen sich wie eine einzige Eingabe verhalten sollen, verwenden Sie Input.get_vector():

# `velocity` will be a Vector2 between `Vector2(-1.0, -1.0)` and `Vector2(1.0, 1.0)`.
# This handles deadzone in a correct way for most use cases.
# The resulting deadzone will have a circular shape as it generally should.
var velocity = Input.get_vector("move_left", "move_right", "move_forward", "move_back")

# The line below is similar to `get_vector()`, except that it handles
# the deadzone in a less optimal way. The resulting deadzone will have
# a square-ish shape when it should ideally have a circular shape.
var velocity = Vector2(
        Input.get_action_strength("move_right") - Input.get_action_strength("move_left"),
        Input.get_action_strength("move_back") - Input.get_action_strength("move_forward")
).limit_length(1.0)
  • Wenn Sie eine Achse haben, die in beide Richtungen gehen kann (wie z.B. ein Gashebel an einem Steuerknüppel), oder wenn Sie separate Achsen einzeln behandeln wollen, verwenden Sie Input.get_axis():

# `walk` will be a floating-point number between `-1.0` and `1.0`.
var walk = Input.get_axis("move_left", "move_right")

# The line above is a shorter form of:
var walk = Input.get_action_strength("move_right") - Input.get_action_strength("move_left")
  • Für andere Arten von analogen Eingängen, wie z.B. die Verarbeitung eines Triggers oder die gleichzeitige Verarbeitung einer Richtung, verwenden Sie Input.get_action_strength():

# `strength` will be a floating-point number between `0.0` and `1.0`.
var strength = Input.get_action_strength("accelerate")

Für nicht-analoge digitale/boolean Eingaben (nur "gedrückt" oder "nicht gedrückt"-Werte), wie z.B. Controller-Buttons, Maustasten oder Tastaturtasten, verwenden Sie Input.is_action_pressed():

# `jumping` will be a boolean with a value of `true` or `false`.
var jumping = Input.is_action_pressed("jump")

Bemerkung

Wenn Sie wissen wollen, ob eine Eingabe im vorherigen Frame gerade eben gedrückt wurde, benutzen Sie Input.is_action_just_pressed() anstelle von Input.is_action_pressed(). Im Gegensatz zu Input.is_action_pressed(), das true zurückgibt, solange die Eingabe gehalten wird, gibt Input.is_action_just_pressed() nur true für einen Frame zurück, nachdem die Taste gedrückt wurde.

In Godot-Versionen vor 3.4, wie 3.3, sind Input.get_vector() und Input.get_axis() nicht verfügbar. Nur Input.get_action_strength() und Input.is_action_pressed() sind in Godot 3.3 verfügbar.

Vibrationen

Vibrationen (auch haptisches Feedback genannt) können verwendet werden, um das Gefühl eines Spiels zu verbessern. In einem Rennspiel können Sie zum Beispiel die Art der Oberfläche, auf der das Auto gerade fährt, durch Vibration vermitteln oder bei einem Unfall eine plötzliche Vibration erzeugen.

Verwenden Sie die Methode start_joy_vibration des Input-Singletons, um die Vibration eines Gamepads zu starten. Verwenden Sie stop_joy_vibration, um die Vibration vorzeitig zu beenden (nützlich, wenn beim Start keine Dauer angegeben wurde).

Auf mobilen Geräten können Sie auch vibrate_handheld verwenden, um das Gerät selbst vibrieren zu lassen (unabhängig vom Gamepad). Unter Android muss dazu die Berechtigung VIBRATE in der Android-Exportvoreinstellung aktiviert werden, bevor das Projekt exportiert wird.

Bemerkung

Vibrationen können für manche Spieler unangenehm sein. Stellen Sie sicher, dass es einen Schieberegler im Spiel gibt, um die Vibration zu deaktivieren oder ihre Intensität zu verringern.

Unterschiede zwischen Tastatur/Maus und Controller-Eingabe

Wenn Sie es gewohnt sind, mit Tastatur- und Mauseingaben umzugehen, werden Sie vielleicht überrascht sein, wie Controller mit bestimmten Situationen umgehen.

Totzone

Im Gegensatz zu Tastaturen und Mäusen verfügen Controller über Achsen mit analogem Eingang. Der Vorteil von Analogeingängen ist, dass sie zusätzliche Flexibilität für Aktionen bieten. Im Gegensatz zu digitalen Eingängen, die nur die Stärken 0.0 und 1.0 liefern können, kann ein analoger Eingang jede Stärke zwischen 0.0 und 1.0 liefern. Der Nachteil ist, dass ohne ein Totzonen-System die Stärke einer analogen Achse niemals gleich 0.0 sein wird, aufgrund der Art, wie der Controller physikalisch aufgebaut ist. Stattdessen wird sie bei einem niedrigen Wert wie 0.062 verweilen. Dieses Phänomen ist als Drifting bekannt und kann bei alten oder defekten Controllern stärker auffallen.

Nehmen wir ein Rennspiel als Beispiel aus der Praxis. Dank der analogen Eingaben können wir das Auto langsam in die eine oder andere Richtung lenken. Ohne ein Totzonen-System würde das Auto jedoch von selbst langsam lenken, auch wenn der Spieler den Joystick nicht berührt. Das liegt daran, dass die Stärke der Richtungsachse nicht gleich 0.0 ist, wenn wir es erwarten. Da wir nicht wollen, dass unser Auto in diesem Fall von selbst lenkt, definieren wir einen "Totzonen"-Wert von 0.2, der alle Eingaben ignoriert, deren Stärke kleiner als 0.2 ist. Ein idealer Wert für die Totzone ist hoch genug, um die Eingaben zu ignorieren, die durch das Abdriften des Joysticks verursacht werden, aber niedrig genug, um die tatsächlichen Eingaben des Spielers nicht zu ignorieren.

Godot verfügt über ein eingebautes Totzonen-System, um dieses Problem zu lösen. Der Standardwert ist 0.5, aber Sie können ihn für jede Aktion auf der Input Map-Tab der Projekteinstellungen anpassen. Für Input.get_vector() kann die Totzone als optionaler fünfter Parameter angegeben werden. Wenn er nicht angegeben wird, wird der durchschnittliche Wert der Totzone aus allen Aktionen im Vektor berechnet.

"Echo"-Events

Im Gegensatz zur Tastatureingabe erzeugt das Drücken einer Controllertaste, z.B. des D-Pads, keine wiederholten Eingabe-Events in festen Intervallen (auch als "Echo"-Ereignisse bekannt). Das liegt daran, dass das Betriebssystem niemals "Echo"-Events für Controllereingaben sendet.

Wenn Sie möchten, dass Controller-Buttons Echo-Events senden, müssen Sie InputEvent-Objekte per Code generieren und sie mit Input.parse_input_event() in regelmäßigen Abständen auslesen. Dies kann mit Hilfe eines Timer-Nodes erreicht werden.

Fenster-Fokus

Im Gegensatz zu Tastatureingaben können Controllereingaben von allen Fenstern des Betriebssystems gesehen werden, auch von nicht fokussierten Fenstern.

Dies ist zwar für die Split-Screen-Funktionalität von Drittanbietern nützlich, kann aber auch nachteilige Auswirkungen haben. Spieler können versehentlich Controller-Eingaben an das laufende Projekt senden, während sie mit einem anderen Fenster interagieren.

Falls Sie Events ignorieren wollen, wenn das Projektfenster nicht fokussiert ist, müssen Sie einen autoload mit dem Namen Focus mit folgendem Skript erstellen und es benutzen, um alle Ihre Inputs zu überprüfen:

# Focus.gd
extends Node

var focused := true

func _notification(what: int) -> void:
    match what:
        NOTIFICATION_APPLICATION_FOCUS_OUT:
            focused = false
        NOTIFICATION_APPLICATION_FOCUS_IN:
            focused = true


func input_is_action_pressed(action: StringName) -> bool:
    if focused:
        return Input.is_action_pressed(action)

    return false


func event_is_action_pressed(event: InputEvent, action: StringName) -> bool:
    if focused:
        return event.is_action_pressed(action)

    return false

Dann verwenden Sie statt Input.is_action_pressed(action) die Funktion Focus.input_is_action_pressed(action), wobei action der Name der Eingabeaktion ist. Anstelle von event.is_action_pressed(action) verwenden Sie Focus.event_is_action_pressed(event, action), wobei event eine InputEvent-Referenz und action der Name der Eingabeaktion ist.

Verhindern des Energiesparmodus

Im Gegensatz zu Tastatur- und Mauseingaben verhindern Controller-Eingaben nicht den Ruhezustand und Energiesparmodi (z. B. das Ausschalten des Bildschirms nach einer bestimmten Zeitspanne).

Um dem entgegenzuwirken, aktiviert Godot standardmäßig die Energiesparvermeidung, wenn ein Projekt ausgeführt wird. Wenn Sie feststellen, dass das System seinen Bildschirm ausschaltet, wenn Sie mit einem Gamepad spielen, überprüfen Sie den Wert von Anzeige > Fenster > Energiesparen > Bildschirm eingeschaltet lassen in den Projekteinstellungen.

Unter Linux setzt die Energiesparvermeidung voraus, dass die Engine in der Lage ist, D-Bus zu verwenden. Prüfen Sie, ob D-Bus installiert und erreichbar ist, wenn Sie das Projekt in einem Flatpak ausführen, da Sandboxing-Einschränkungen dies standardmäßig unmöglich machen können.

Fehlersuche

Siehe auch

Sie können eine Liste der bekannten Issues mit der Controller-Unterstützung auf GitHub einsehen.

Mein Controller wird von Godot nicht erkannt.

Überprüfen Sie zunächst, ob Ihr Controller von anderen Anwendungen erkannt wird. Sie können die Website Gamepad Tester verwenden, um zu überprüfen, ob Ihr Controller erkannt wird.

On Windows Godot only supports up to 4 controllers at a time. This is because Godot uses the XInput API, which is limited to supporting 4 controllers at once. Additional controllers above this limit are ignored by Godot.

Mein Controller hat falsch zugewiesene Tasten oder Achsen.

Wenn Ihr Controller über ein Dienstprogramm zur Firmware-Aktualisierung verfügt, sollten Sie es zunächst ausführen, um die neuesten Fixes vom Hersteller zu erhalten. Die Firmware von Xbox One- und Xbox Series-Controllern kann beispielsweise mit der Xbox Accessories-App aktualisiert werden. (Diese Anwendung läuft nur unter Windows, Sie müssen also einen Windows-Rechner oder eine virtuelle Windows-Maschine mit USB-Unterstützung verwenden, um die Firmware des Controllers zu aktualisieren.) Nachdem Sie die Firmware des Controllers aktualisiert haben, trennen Sie das Pairing des Controllers und verbinden Sie ihn erneut mit Ihrem PC, wenn Sie den Controller im drahtlosen Modus verwenden.

Wenn Tasten falsch zugeordnet sind, kann dies an einer fehlerhaften Zuordnung aus der SDL Game Controller Database liegen. Sie können ein aktualisiertes Mapping beisteuern, das in die nächste Godot-Version aufgenommen wird, indem Sie einen Pull-Request im verlinkten Repository öffnen.

Es gibt viele Möglichkeiten, Mappings zu erstellen. Eine Möglichkeit ist die Verwendung des Mapping-Assistenten in der offiziellen Joypads-Demo. Sobald Sie ein funktionierendes Mapping für Ihren Controller haben, können Sie es testen, indem Sie die Umgebungsvariable SDL_GAMECONTROLLERCONFIG definieren, bevor Sie Godot starten:

export SDL_GAMECONTROLLERCONFIG="your:mapping:here"
./path/to/godot.x86_64

Um Mappings auf Nicht-Desktop-Plattformen zu testen oder um Ihr Projekt mit zusätzlichen Controller-Mappings zu verteilen, können Sie diese durch den Aufruf von Input.add_joy_mapping() so früh wie möglich in der _ready() Funktion eines Skripts hinzufügen.

Mein Controller funktioniert auf einer bestimmten Plattform, aber nicht auf einer anderen Plattform.

Linux

Wenn Sie eine selbst kompilierte Engine-Binärdatei verwenden, stellen Sie sicher, dass sie mit udev-Unterstützung kompiliert wurde. Diese ist standardmäßig aktiviert, aber es ist möglich, die udev-Unterstützung zu deaktivieren, indem man udev=no auf der SCons-Kommandozeile angibt. Wenn Sie eine Engine-Binärdatei verwenden, die von einer Linux-Distribution geliefert wird, überprüfen Sie, ob sie mit udev-Unterstützung kompiliert wurde.

Controller können auch ohne udev-Unterstützung funktionieren, aber es ist weniger zuverlässig, da regelmäßiges Polling verwendet werden muss, um zu überprüfen, ob die Controller während des Spiels angeschlossen oder getrennt werden (Hotplugging).

HTML5

Die Unterstützung für Controller bei HTML5-Spielen ist im Vergleich zu "nativen" Plattformen oft weniger zuverlässig. Die Qualität der Controller-Unterstützung ist von Browser zu Browser sehr unterschiedlich. Daher müssen Sie Ihre Spieler möglicherweise anweisen, einen anderen Browser zu verwenden, wenn sie ihren Controller nicht zum Laufen bringen können.