Controllers, gamepads, and joysticks
SDL game controller database. Controllers are supported on Windows, macOS, Linux, Android, iOS, and HTML5. HOTAS are less tested and may not always work as expected. Overriding force feedback for those devices is also not implemented yet. If you have access to one of those devices, don’t hesitate to report bugs on GitHub. In this guide, you will learn:
- How to write your input logic to support both keyboard and controller inputs.
- How controllers can behave differently from keyboard/mouse input.
- Troubleshooting issues with controllers in Godot.
Supporting universal input
input actions in the Project Settings which will then refer to specified key and controller inputs. Using InputEvent page. Note Unlike keyboard input, supporting both mouse and controller input for an action (such as looking around in a first-person game) will require different code paths since these have to be handled separately.Which Input singleton method should I use?
There are 3 ways to get input in an analog-aware way: Input.get_vector(): GDScript C## `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")).clamped(1)
// `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.Vector2 velocity = Input.GetVector("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.Vector2 velocity = new Vector2(Input.GetActionStrength("move_right") - Input.GetActionStrength("move_left"), Input.GetActionStrength("move_back") - Input.GetActionStrength("move_forward")).Clamped(1);
Input.get_axis(): GDScript C## `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")
// `walk` will be a floating-point number between `-1.0` and `1.0`.float walk = Input.GetAxis("move_left", "move_right");// The line above is a shorter form of:float walk = Input.GetActionStrength("move_right") - Input.GetActionStrength("move_left");
Input.get_action_strength(): GDScript C## `strength` will be a floating-point number between `0.0` and `1.0`.var strength = Input.get_action_strength("accelerate")
// `strength` will be a floating-point number between `0.0` and `1.0`.float strength = Input.GetActionStrength("accelerate");
Input.is_action_pressed(): GDScript
C## `jumping` will be a boolean with a value of `true` or `false`.var jumping = Input.is_action_pressed("jump")
// `jumping` will be a boolean with a value of `true` or `false`.bool jumping = Input.IsActionPressed("jump");
Input.get_vector()andInput.get_axis()aren’t available. OnlyInput.get_action_strength()andInput.is_action_pressed()are available in Godot 3.3.Differences between keyboard/mouse and controller input
If you’re used to handling keyboard and mouse input, you may be surprised by how controllers handle specific situations.Dead zone
analog inputs. The upside of analog inputs is that they offer additional flexibility for actions. Unlike digital inputs which can only provide strengths of0.0and1.0, an analog input can provide any strength between0.0and1.0. The downside is that without a deadzone system, an analog axis’ strength will never be equal to0.0due to how the controller is physically built. Instead, it will linger at a low value such as0.062. This phenomenon is known as drifting and can be more noticeable on old or faulty controllers.0.0when we expect it to. Since we don’t want our car to steer by itself in this case, we define a “dead zone” value of0.2which will ignore all input whose strength is lower than0.2. An ideal dead zone value is high enough to ignore the input caused by joystick drifting, but is low enough to not ignore actual input from the player.0.2, but you can increase it or decrease it on a per-action basis in the Project Settings’ Input Map tab. ForInput.get_vector(), the deadzone can be specified, or otherwise it will calculate the average deadzone value from all of the actions in the vector.“Echo” events
not generate repeated input events at fixed intervals (also known as “echo” events). This is because the operating system never sends “echo” events for controller input in the first place. InputEvent objects by code and parse them using Input.parse_input_event() at regular intervals. This can be accomplished with the help of a Timer node.Troubleshooting
See also known issues with controller support on GitHub.My controller isn’t recognized by Godot.
Gamepad Tester website to confirm that your controller is recognized.My controller has incorrectly mapped buttons or axes.
SDL game controller database. You can contribute an updated mapping to be included in the next Godot version by opening a pull request on the linked repository. official Joypads demo. Once you have a working mapping for your controller, you can test it by defining theSDL_GAMECONTROLLERCONFIGenvironment variable before running Godot: Linux/macOSWindows (cmd)Windows (powershell)export SDL_GAMECONTROLLERCONFIG="your:mapping:here"./path/to/godot.x86_64
set SDL_GAMECONTROLLERCONFIG=your:mapping:herepath\to\godot.exe
Input.add_joy_mapping() as early as possible in a script’s$env:SDL_GAMECONTROLLERCONFIG="your:mapping:here"path\to\godot.exe
_ready()function.My controller works on a given platform, but not on another platform.
Linux
without udev support unlessudev=yeswas passed on the SCons command line. This made controller hotplugging support unavailable in self-compiled binaries.HTML5
HTML5 controller support is often less reliable compared to “native” platforms. The quality of controller support tends to vary wildly across browsers. As a result, you may have to instruct your players to use a different browser if they can’t get their controller to work. controller support was significantly improved in Godot 3.3 and later.
