|
@@ -0,0 +1,246 @@
|
|
|
+.. _doc_controllers_gamepads_joysticks:
|
|
|
+
|
|
|
+Controllers, gamepads, and joysticks
|
|
|
+====================================
|
|
|
+
|
|
|
+Godot supports hundreds of controller models thanks to the community-sourced
|
|
|
+`SDL game controller database <https://github.com/gabomdq/SDL_GameControllerDB>`__.
|
|
|
+
|
|
|
+Controllers are supported on Windows, macOS, Linux, Android, iOS, and HTML5.
|
|
|
+
|
|
|
+Note that more specialized devices such as steering wheels, rudder pedals and
|
|
|
+`HOTAS <https://en.wikipedia.org/wiki/HOTAS>`__ are less tested and may not
|
|
|
+always work as expected. If you have access to one of those devices, don't hesitate to
|
|
|
+`report bugs on GitHub <https://github.com/godotengine/godot/blob/master/CONTRIBUTING.md#reporting-bugs>`__.
|
|
|
+
|
|
|
+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
|
|
|
+--------------------------
|
|
|
+
|
|
|
+Thanks to Godot's input action system, Godot makes it possible to support both
|
|
|
+keyboard and controller input without having to write separate code paths.
|
|
|
+Instead of hardcoding keys or controller buttons in your scripts, you should
|
|
|
+create *input actions* in the Project Settings which will then refer to
|
|
|
+specified key and controller inputs.
|
|
|
+
|
|
|
+Input actions are explained in detail on the :ref:`doc_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?
|
|
|
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
|
+
|
|
|
+In Godot 4.0, there are 3 ways to get input in an analog-aware way:
|
|
|
+
|
|
|
+- When you have two axes (such as joystick or WASD movement) and want both
|
|
|
+ axes to behave as a single input, use ``Input.get_vector()``:
|
|
|
+
|
|
|
+.. tabs::
|
|
|
+ .. code-tab:: gdscript GDScript
|
|
|
+
|
|
|
+ # `velocity` will be a Vector2 between `Vector2(-1.0, -1.0)` and `Vector2(1.0, 1.0)`.
|
|
|
+ var velocity = Input.get_vector("move_left", "move_right", "move_forward", "move_back")
|
|
|
+
|
|
|
+ # The line above is a shorter form of:
|
|
|
+ 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)
|
|
|
+
|
|
|
+ .. code-tab:: csharp
|
|
|
+
|
|
|
+ // `velocity` will be a Vector2 between `Vector2(-1.0, -1.0)` and `Vector2(1.0, 1.0)`.
|
|
|
+ Vector2 velocity = Input.GetVector("move_left", "move_right", "move_forward", "move_back");
|
|
|
+
|
|
|
+ // The line above is a shorter form of:
|
|
|
+ Vector2 velocity = new Vector2(Input.GetActionStrength("move_right") - Input.GetActionStrength("move_left"),
|
|
|
+ Input.GetActionStrength("move_back") - Input.GetActionStrength("move_forward")).Clamped(1);
|
|
|
+
|
|
|
+- When you have one axis that can go both ways (such as a throttle on a
|
|
|
+ flight stick), or when you want to handle separate axes individually,
|
|
|
+ use ``Input.get_axis()``:
|
|
|
+
|
|
|
+.. tabs::
|
|
|
+ .. code-tab:: gdscript GDScript
|
|
|
+
|
|
|
+ # `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")
|
|
|
+
|
|
|
+ .. code-tab:: csharp
|
|
|
+
|
|
|
+ // `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");
|
|
|
+
|
|
|
+- For other types of analog input, such as handling a trigger or handling
|
|
|
+ one direction at a time, use ``Input.get_action_strength()``:
|
|
|
+
|
|
|
+.. tabs::
|
|
|
+ .. code-tab:: gdscript GDScript
|
|
|
+
|
|
|
+ # `strength` will be a floating-point number between `0.0` and `1.0`.
|
|
|
+ var strength = Input.get_action_strength("accelerate")
|
|
|
+
|
|
|
+ .. code-tab:: csharp
|
|
|
+
|
|
|
+ // `strength` will be a floating-point number between `0.0` and `1.0`.
|
|
|
+ float strength = Input.GetActionStrength("accelerate");
|
|
|
+
|
|
|
+For non-analog digital/boolean input (only "pressed" or "not pressed" values),
|
|
|
+such as controller buttons, mouse buttons or keyboard keys,
|
|
|
+use ``Input.is_action_pressed()``:
|
|
|
+
|
|
|
+.. tabs::
|
|
|
+ .. code-tab:: gdscript GDScript
|
|
|
+
|
|
|
+ # `jumping` will be a boolean with a value of `true` or `false`.
|
|
|
+ var jumping = Input.is_action_pressed("jump")
|
|
|
+
|
|
|
+.. tabs::
|
|
|
+ .. code-tab:: csharp
|
|
|
+
|
|
|
+ // `jumping` will be a boolean with a value of `true` or `false`.
|
|
|
+ bool jumping = Input.IsActionPressed("jump");
|
|
|
+
|
|
|
+In Godot versions before 4.0, such as 3.2, ``Input.get_vector()`` and
|
|
|
+``Input.get_axis()`` aren't available. Only ``Input.get_action_strength()``
|
|
|
+and ``Input.is_action_pressed()`` are available in Godot 3.2.
|
|
|
+
|
|
|
+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
|
|
|
+^^^^^^^^^
|
|
|
+
|
|
|
+Unlike keyboards and mice, controllers offer axes with *analog* inputs. The
|
|
|
+upside of analog inputs is that they offer additional flexibility for actions.
|
|
|
+Unlike digital inputs which can only provide strengths of ``0.0`` and ``1.0``,
|
|
|
+an analog input can provide *any* strength between ``0.0`` and ``1.0``. The
|
|
|
+downside is that without a deadzone system, an analog axis' strength will never
|
|
|
+be equal to ``0.0`` due to how the controller is physically built. Instead, it
|
|
|
+will linger at a low value such as ``0.062``. This phenomenon is known as
|
|
|
+*drifting* and can be more noticeable on old or faulty controllers.
|
|
|
+
|
|
|
+Let's take a racing game as a real-world example. Thanks to analog inputs, we
|
|
|
+can steer the car slowly in one direction or another. However, without a
|
|
|
+deadzone system, the car would slowly steer by itself even if the player isn't
|
|
|
+touching the joystick. This is because the directional axis strength won't be
|
|
|
+equal to ``0.0`` when we expect it to. Since we don't want our car to steer by
|
|
|
+itself in this case, we define a "dead zone" value of ``0.2`` which will ignore
|
|
|
+all input whose strength is lower than ``0.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.
|
|
|
+
|
|
|
+Godot features a built-in dead zone system to tackle this problem. The default
|
|
|
+value is ``0.2``, but you can increase it or decrease it on a per-action basis
|
|
|
+in the Project Settings' Input Map tab.
|
|
|
+For ``Input.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
|
|
|
+^^^^^^^^^^^^^
|
|
|
+
|
|
|
+Unlike keyboard input, holding down a controller button such as a D-pad
|
|
|
+direction will **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.
|
|
|
+
|
|
|
+If you want controller buttons to send echo events, you will have to generate
|
|
|
+:ref:`class_InputEvent` objects by code and parse them using
|
|
|
+:ref:`Input.parse_input_event() <class_Input_method_parse_input_event>`
|
|
|
+at regular intervals. This can be accomplished
|
|
|
+with the help of a :ref:`class_Timer` node.
|
|
|
+
|
|
|
+Troubleshooting
|
|
|
+---------------
|
|
|
+
|
|
|
+.. seealso::
|
|
|
+
|
|
|
+ You can view a list of
|
|
|
+ `known issues with controller support <https://github.com/godotengine/godot/issues?q=is%3Aopen+is%3Aissue+label%3Atopic%3Ainput+gamepad>`__
|
|
|
+ on GitHub.
|
|
|
+
|
|
|
+My controller isn't recognized by Godot.
|
|
|
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
|
+
|
|
|
+First, check that your controller is recognized by other applications. You can
|
|
|
+use the `Gamepad Tester <https://gamepad-tester.com/>`__ website to confirm that
|
|
|
+your controller is recognized.
|
|
|
+
|
|
|
+My controller has incorrectly mapped buttons or axes.
|
|
|
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
|
+
|
|
|
+If buttons are incorrectly mapped, this may be due to an erroneous mapping from
|
|
|
+the `SDL game controller database <https://github.com/gabomdq/SDL_GameControllerDB>`__.
|
|
|
+You can contribute an updated mapping to be included in the next Godot version
|
|
|
+by opening a pull request on the linked repository.
|
|
|
+
|
|
|
+There are many ways to create mappings. One option is to use the mapping wizard
|
|
|
+in the `official Joypads demo <https://godotengine.org/asset-library/asset/140>`__.
|
|
|
+Once you have a working mapping for your controller, you can test it by defining
|
|
|
+the ``SDL_GAMECONTROLLERCONFIG`` environment variable before running Godot:
|
|
|
+
|
|
|
+.. tabs::
|
|
|
+ .. code-tab:: bash Linux/macOS
|
|
|
+
|
|
|
+ export SDL_GAMECONTROLLERCONFIG="your:mapping:here"
|
|
|
+ ./path/to/godot.x86_64
|
|
|
+
|
|
|
+ .. code-tab:: bat Windows (cmd)
|
|
|
+
|
|
|
+ set SDL_GAMECONTROLLERCONFIG=your:mapping:here
|
|
|
+ path\to\godot.exe
|
|
|
+
|
|
|
+ .. code-tab:: powershell Windows (powershell)
|
|
|
+
|
|
|
+ $env:SDL_GAMECONTROLLERCONFIG="your:mapping:here"
|
|
|
+ path\to\godot.exe
|
|
|
+
|
|
|
+To test mappings on non-desktop platforms or to distribute your project with
|
|
|
+additional controller mappings, you can add them by calling
|
|
|
+:ref:`Input.add_joy_mapping() <class_Input_method_add_joy_mapping>`
|
|
|
+as early as possible in a script's ``_ready()`` function.
|
|
|
+
|
|
|
+My controller works on a given platform, but not on another platform.
|
|
|
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
|
+
|
|
|
+macOS
|
|
|
+~~~~~
|
|
|
+
|
|
|
+Controllers are currently only supported on x86-based Macs. This means
|
|
|
+controllers won't work on Macs featuring ARM processors such as the Apple M1.
|
|
|
+
|
|
|
+Linux
|
|
|
+~~~~~
|
|
|
+
|
|
|
+Prior to Godot 3.2.4, official Godot binaries were compiled with udev support
|
|
|
+but self-compiled binaries were compiled *without* udev support unless
|
|
|
+``udev=yes`` was 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.
|
|
|
+
|
|
|
+Also, note that
|
|
|
+`controller support was significantly improved <https://github.com/godotengine/godot/pull/45078>`__
|
|
|
+in Godot 3.2.4 and later.
|