controllers_gamepads_joysticks.rst 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271
  1. .. _doc_controllers_gamepads_joysticks:
  2. Controllers, gamepads, and joysticks
  3. ====================================
  4. Godot supports hundreds of controller models thanks to the community-sourced
  5. `SDL game controller database <https://github.com/gabomdq/SDL_GameControllerDB>`__.
  6. Controllers are supported on Windows, macOS, Linux, Android, iOS, and HTML5.
  7. Note that more specialized devices such as steering wheels, rudder pedals and
  8. `HOTAS <https://en.wikipedia.org/wiki/HOTAS>`__ are less tested and may not
  9. always work as expected. If you have access to one of those devices, don't hesitate to
  10. `report bugs on GitHub <https://github.com/godotengine/godot/blob/master/CONTRIBUTING.md#reporting-bugs>`__.
  11. In this guide, you will learn:
  12. - **How to write your input logic to support both keyboard and controller inputs.**
  13. - **How controllers can behave differently from keyboard/mouse input.**
  14. - **Troubleshooting issues with controllers in Godot.**
  15. Supporting universal input
  16. --------------------------
  17. Thanks to Godot's input action system, Godot makes it possible to support both
  18. keyboard and controller input without having to write separate code paths.
  19. Instead of hardcoding keys or controller buttons in your scripts, you should
  20. create *input actions* in the Project Settings which will then refer to
  21. specified key and controller inputs.
  22. Input actions are explained in detail on the :ref:`doc_inputevent` page.
  23. .. note::
  24. Unlike keyboard input, supporting both mouse and controller input for an
  25. action (such as looking around in a first-person game) will require
  26. different code paths since these have to be handled separately.
  27. Which Input singleton method should I use?
  28. ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  29. There are 3 ways to get input in an analog-aware way:
  30. - When you have two axes (such as joystick or WASD movement) and want both
  31. axes to behave as a single input, use ``Input.get_vector()``:
  32. .. tabs::
  33. .. code-tab:: gdscript GDScript
  34. # `velocity` will be a Vector2 between `Vector2(-1.0, -1.0)` and `Vector2(1.0, 1.0)`.
  35. # This handles deadzone in a correct way for most use cases.
  36. # The resulting deadzone will have a circular shape as it generally should.
  37. var velocity = Input.get_vector("move_left", "move_right", "move_forward", "move_back")
  38. # The line below is similar to `get_vector()`, except that it handles
  39. # the deadzone in a less optimal way. The resulting deadzone will have
  40. # a square-ish shape when it should ideally have a circular shape.
  41. var velocity = Vector2(Input.get_action_strength("move_right") - Input.get_action_strength("move_left"),
  42. Input.get_action_strength("move_back") - Input.get_action_strength("move_forward")).clamped(1)
  43. .. code-tab:: csharp
  44. // `velocity` will be a Vector2 between `Vector2(-1.0, -1.0)` and `Vector2(1.0, 1.0)`.
  45. // This handles deadzone in a correct way for most use cases.
  46. // The resulting deadzone will have a circular shape as it generally should.
  47. Vector2 velocity = Input.GetVector("move_left", "move_right", "move_forward", "move_back");
  48. // The line below is similar to `get_vector()`, except that it handles
  49. // the deadzone in a less optimal way. The resulting deadzone will have
  50. // a square-ish shape when it should ideally have a circular shape.
  51. Vector2 velocity = new Vector2(Input.GetActionStrength("move_right") - Input.GetActionStrength("move_left"),
  52. Input.GetActionStrength("move_back") - Input.GetActionStrength("move_forward")).Clamped(1);
  53. - When you have one axis that can go both ways (such as a throttle on a
  54. flight stick), or when you want to handle separate axes individually,
  55. use ``Input.get_axis()``:
  56. .. tabs::
  57. .. code-tab:: gdscript GDScript
  58. # `walk` will be a floating-point number between `-1.0` and `1.0`.
  59. var walk = Input.get_axis("move_left", "move_right")
  60. # The line above is a shorter form of:
  61. var walk = Input.get_action_strength("move_right") - Input.get_action_strength("move_left")
  62. .. code-tab:: csharp
  63. // `walk` will be a floating-point number between `-1.0` and `1.0`.
  64. float walk = Input.GetAxis("move_left", "move_right");
  65. // The line above is a shorter form of:
  66. float walk = Input.GetActionStrength("move_right") - Input.GetActionStrength("move_left");
  67. - For other types of analog input, such as handling a trigger or handling
  68. one direction at a time, use ``Input.get_action_strength()``:
  69. .. tabs::
  70. .. code-tab:: gdscript GDScript
  71. # `strength` will be a floating-point number between `0.0` and `1.0`.
  72. var strength = Input.get_action_strength("accelerate")
  73. .. code-tab:: csharp
  74. // `strength` will be a floating-point number between `0.0` and `1.0`.
  75. float strength = Input.GetActionStrength("accelerate");
  76. For non-analog digital/boolean input (only "pressed" or "not pressed" values),
  77. such as controller buttons, mouse buttons or keyboard keys,
  78. use ``Input.is_action_pressed()``:
  79. .. tabs::
  80. .. code-tab:: gdscript GDScript
  81. # `jumping` will be a boolean with a value of `true` or `false`.
  82. var jumping = Input.is_action_pressed("jump")
  83. .. code-tab:: csharp
  84. // `jumping` will be a boolean with a value of `true` or `false`.
  85. bool jumping = Input.IsActionPressed("jump");
  86. .. note::
  87. If you need to know whether an input was *just* pressed in the previous
  88. frame, use ``Input.is_action_just_pressed()`` instead of
  89. ``Input.is_action_pressed()``. Unlike ``Input.is_action_pressed()`` which
  90. returns ``true`` as long as the input is
  91. held,``Input.is_action_just_pressed()`` will only return ``true`` for one
  92. frame after the button has been pressed.
  93. In Godot versions before 3.4, such as 3.3, ``Input.get_vector()`` and
  94. ``Input.get_axis()`` aren't available. Only ``Input.get_action_strength()``
  95. and ``Input.is_action_pressed()`` are available in Godot 3.3.
  96. Differences between keyboard/mouse and controller input
  97. -------------------------------------------------------
  98. If you're used to handling keyboard and mouse input, you may be surprised by how
  99. controllers handle specific situations.
  100. Dead zone
  101. ^^^^^^^^^
  102. Unlike keyboards and mice, controllers offer axes with *analog* inputs. The
  103. upside of analog inputs is that they offer additional flexibility for actions.
  104. Unlike digital inputs which can only provide strengths of ``0.0`` and ``1.0``,
  105. an analog input can provide *any* strength between ``0.0`` and ``1.0``. The
  106. downside is that without a deadzone system, an analog axis' strength will never
  107. be equal to ``0.0`` due to how the controller is physically built. Instead, it
  108. will linger at a low value such as ``0.062``. This phenomenon is known as
  109. *drifting* and can be more noticeable on old or faulty controllers.
  110. Let's take a racing game as a real-world example. Thanks to analog inputs, we
  111. can steer the car slowly in one direction or another. However, without a
  112. deadzone system, the car would slowly steer by itself even if the player isn't
  113. touching the joystick. This is because the directional axis strength won't be
  114. equal to ``0.0`` when we expect it to. Since we don't want our car to steer by
  115. itself in this case, we define a "dead zone" value of ``0.2`` which will ignore
  116. all input whose strength is lower than ``0.2``. An ideal dead zone value is high
  117. enough to ignore the input caused by joystick drifting, but is low enough to not
  118. ignore actual input from the player.
  119. Godot features a built-in dead zone system to tackle this problem. The default
  120. value is ``0.2``, but you can increase it or decrease it on a per-action basis
  121. in the Project Settings' Input Map tab.
  122. For ``Input.get_vector()``, the deadzone can be specified, or otherwise it
  123. will calculate the average deadzone value from all of the actions in the vector.
  124. "Echo" events
  125. ^^^^^^^^^^^^^
  126. Unlike keyboard input, holding down a controller button such as a D-pad
  127. direction will **not** generate repeated input events at fixed intervals (also
  128. known as "echo" events). This is because the operating system never sends "echo"
  129. events for controller input in the first place.
  130. If you want controller buttons to send echo events, you will have to generate
  131. :ref:`class_InputEvent` objects by code and parse them using
  132. :ref:`Input.parse_input_event() <class_Input_method_parse_input_event>`
  133. at regular intervals. This can be accomplished
  134. with the help of a :ref:`class_Timer` node.
  135. Troubleshooting
  136. ---------------
  137. .. seealso::
  138. You can view a list of
  139. `known issues with controller support <https://github.com/godotengine/godot/issues?q=is%3Aopen+is%3Aissue+label%3Atopic%3Ainput+gamepad>`__
  140. on GitHub.
  141. My controller isn't recognized by Godot.
  142. ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  143. First, check that your controller is recognized by other applications. You can
  144. use the `Gamepad Tester <https://gamepad-tester.com/>`__ website to confirm that
  145. your controller is recognized.
  146. My controller has incorrectly mapped buttons or axes.
  147. ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  148. First, if your controller provides some kind of firmware update utility,
  149. make sure to run it to get the latest fixes from the manufacturer. For instance,
  150. Xbox One and Xbox Series controllers can have their firmware updated using the
  151. `Xbox Accessories app <https://www.microsoft.com/en-us/p/xbox-accessories/9nblggh30xj3>`__.
  152. (This application only runs on Windows, so you have to use a Windows machine
  153. or a Windows virtual machine with USB support to update the controller's firmware.)
  154. After updating the controller's firmware, unpair the controller and pair it again
  155. with your PC if you are using the controller in wireless mode.
  156. If buttons are incorrectly mapped, this may be due to an erroneous mapping from
  157. the `SDL game controller database <https://github.com/gabomdq/SDL_GameControllerDB>`__.
  158. You can contribute an updated mapping to be included in the next Godot version
  159. by opening a pull request on the linked repository.
  160. There are many ways to create mappings. One option is to use the mapping wizard
  161. in the `official Joypads demo <https://godotengine.org/asset-library/asset/140>`__.
  162. Once you have a working mapping for your controller, you can test it by defining
  163. the ``SDL_GAMECONTROLLERCONFIG`` environment variable before running Godot:
  164. .. tabs::
  165. .. code-tab:: bash Linux/macOS
  166. export SDL_GAMECONTROLLERCONFIG="your:mapping:here"
  167. ./path/to/godot.x86_64
  168. .. code-tab:: bat Windows (cmd)
  169. set SDL_GAMECONTROLLERCONFIG=your:mapping:here
  170. path\to\godot.exe
  171. .. code-tab:: powershell Windows (PowerShell)
  172. $env:SDL_GAMECONTROLLERCONFIG="your:mapping:here"
  173. path\to\godot.exe
  174. To test mappings on non-desktop platforms or to distribute your project with
  175. additional controller mappings, you can add them by calling
  176. :ref:`Input.add_joy_mapping() <class_Input_method_add_joy_mapping>`
  177. as early as possible in a script's ``_ready()`` function.
  178. My controller works on a given platform, but not on another platform.
  179. ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  180. macOS
  181. ~~~~~
  182. Controllers are currently only supported on x86-based Macs. This means
  183. controllers won't work on Macs featuring ARM processors such as the Apple M1.
  184. Linux
  185. ~~~~~
  186. Prior to Godot 3.2.4, official Godot binaries were compiled with udev support
  187. but self-compiled binaries were compiled *without* udev support unless
  188. ``udev=yes`` was passed on the SCons command line. This made controller
  189. hotplugging support unavailable in self-compiled binaries.
  190. HTML5
  191. ~~~~~
  192. HTML5 controller support is often less reliable compared to "native" platforms.
  193. The quality of controller support tends to vary wildly across browsers. As a
  194. result, you may have to instruct your players to use a different browser if they
  195. can't get their controller to work.
  196. Also, note that
  197. `controller support was significantly improved <https://github.com/godotengine/godot/pull/45078>`__
  198. in Godot 3.2.4 and later.