inputevent.rst 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264
  1. .. _doc_inputevent:
  2. Using InputEvent
  3. ================
  4. What is it?
  5. -----------
  6. Managing input is usually complex, no matter the OS or platform. To ease
  7. this a little, a special built-in type is provided, :ref:`InputEvent <class_InputEvent>`.
  8. This datatype can be configured to contain several types of input
  9. events. Input events travel through the engine and can be received in
  10. multiple locations, depending on the purpose.
  11. Here is a quick example, closing your game if the escape key is hit:
  12. .. tabs::
  13. .. code-tab:: gdscript GDScript
  14. func _unhandled_input(event):
  15. if event is InputEventKey:
  16. if event.pressed and event.keycode == KEY_ESCAPE:
  17. get_tree().quit()
  18. .. code-tab:: csharp
  19. public override void _UnhandledInput(InputEvent @event)
  20. {
  21. if (@event is InputEventKey eventKey)
  22. {
  23. if (eventKey.Pressed && eventKey.Keycode == Key.Escape)
  24. {
  25. GetTree().Quit();
  26. }
  27. }
  28. }
  29. However, it is cleaner and more flexible to use the provided :ref:`InputMap <class_InputMap>` feature,
  30. which allows you to define input actions and assign them different keys. This way,
  31. you can define multiple keys for the same action (e.g. the keyboard escape key and the start button on a gamepad).
  32. You can then more easily change this mapping in the project settings without updating your code,
  33. and even build a key mapping feature on top of it to allow your game to change the key mapping at runtime!
  34. You can set up your InputMap under **Project > Project Settings > Input Map** and then use those actions like this:
  35. .. tabs::
  36. .. code-tab:: gdscript GDScript
  37. func _process(delta):
  38. if Input.is_action_pressed("ui_right"):
  39. # Move right.
  40. .. code-tab:: csharp
  41. public override void _Process(double delta)
  42. {
  43. if (Input.IsActionPressed("ui_right"))
  44. {
  45. // Move right.
  46. }
  47. }
  48. How does it work?
  49. -----------------
  50. Every input event is originated from the user/player (though it's
  51. possible to generate an InputEvent and feed them back to the engine,
  52. which is useful for gestures). The DisplayServer for each platform will read
  53. events from the operating system, then feed them to the root :ref:`Window <class_Window>`.
  54. The window's :ref:`Viewport <class_Viewport>` does quite a lot of stuff with the
  55. received input, in order:
  56. .. image:: img/input_event_flow.webp
  57. 1. If the Viewport is embedding Windows, the Viewport tries to interpret the event in its
  58. capability as a Window-Manager (e.g. for resizing or moving Windows).
  59. 2. Next if an embedded Window is focused, the event is sent to that Window and processed in
  60. the Window's Viewport and afterwards treated as handled. If no embedded Window is focused,
  61. the event is sent to the nodes of the current viewport in the following order.
  62. 3. First of all, the standard :ref:`Node._input() <class_Node_private_method__input>` function
  63. will be called in any node that overrides it (and hasn't disabled input processing with :ref:`Node.set_process_input() <class_Node_method_set_process_input>`).
  64. If any function consumes the event, it can call :ref:`Viewport.set_input_as_handled() <class_Viewport_method_set_input_as_handled>`, and the event will
  65. not spread any more. This ensures that you can filter all events of interest, even before the GUI.
  66. For gameplay input, :ref:`Node._unhandled_input() <class_Node_private_method__unhandled_input>` is generally a better fit, because it allows the GUI to intercept the events.
  67. 4. Second, it will try to feed the input to the GUI, and see if any
  68. control can receive it. If so, the :ref:`Control <class_Control>` will be called via the
  69. virtual function :ref:`Control._gui_input() <class_Control_private_method__gui_input>` and the signal
  70. "gui_input" will be emitted (this function is re-implementable by
  71. script by inheriting from it). If the control wants to "consume" the
  72. event, it will call :ref:`Control.accept_event() <class_Control_method_accept_event>` and the event will
  73. not spread any more. Use the :ref:`Control.mouse_filter <class_Control_property_mouse_filter>`
  74. property to control whether a :ref:`Control <class_Control>` is notified
  75. of mouse events via :ref:`Control._gui_input() <class_Control_private_method__gui_input>`
  76. callback, and whether these events are propagated further.
  77. 5. If so far no one consumed the event, the :ref:`Node._shortcut_input() <class_Node_private_method__shortcut_input>` callback
  78. will be called if overridden (and not disabled with
  79. :ref:`Node.set_process_shortcut_input() <class_Node_method_set_process_shortcut_input>`).
  80. This happens only for :ref:`InputEventKey <class_InputEventKey>`,
  81. :ref:`InputEventShortcut <class_InputEventShortcut>` and :ref:`InputEventJoypadButton <class_InputEventJoypadButton>`.
  82. If any function consumes the event, it can call :ref:`Viewport.set_input_as_handled() <class_Viewport_method_set_input_as_handled>`, and the
  83. event will not spread any more. The shortcut input callback is ideal for treating events that are intended as shortcuts.
  84. 6. If so far no one consumed the event, the :ref:`Node._unhandled_key_input() <class_Node_private_method__unhandled_key_input>` callback
  85. will be called if overridden (and not disabled with
  86. :ref:`Node.set_process_unhandled_key_input() <class_Node_method_set_process_unhandled_key_input>`).
  87. This happens only if the event is an :ref:`InputEventKey <class_InputEventKey>`.
  88. If any function consumes the event, it can call :ref:`Viewport.set_input_as_handled() <class_Viewport_method_set_input_as_handled>`, and the
  89. event will not spread any more. The unhandled key input callback is ideal for key events.
  90. 7. If so far no one consumed the event, the :ref:`Node._unhandled_input() <class_Node_private_method__unhandled_input>` callback
  91. will be called if overridden (and not disabled with
  92. :ref:`Node.set_process_unhandled_input() <class_Node_method_set_process_unhandled_input>`).
  93. If any function consumes the event, it can call :ref:`Viewport.set_input_as_handled() <class_Viewport_method_set_input_as_handled>`, and the
  94. event will not spread any more. The unhandled input callback is ideal for full-screen gameplay events, so they are not received when a GUI is active.
  95. 8. If no one wanted the event so far, and :ref:`Object Picking <class_viewport_property_physics_object_picking>`
  96. is turned on, the event is used for object picking. For the root viewport, this can also be
  97. enabled in :ref:`Project Settings <class_ProjectSettings_property_physics/common/enable_object_picking>`.
  98. In the case of a 3D scene if a :ref:`Camera3D <class_Camera3D>` is assigned to the Viewport, a ray
  99. to the physics world (in the ray direction from the click) will be cast. If this ray hits an object,
  100. it will call the :ref:`CollisionObject3D._input_event() <class_CollisionObject3D_private_method__input_event>`
  101. function in the relevant physics object.
  102. In the case of a 2D scene, conceptually the same happens with :ref:`CollisionObject2D._input_event() <class_CollisionObject2D_private_method__input_event>`.
  103. When sending events to its child and descendant nodes, the viewport will do so, as depicted in
  104. the following graphic, in a reverse depth-first order, starting with the node at the bottom of
  105. the scene tree, and ending at the root node. Excluded from this process are Windows
  106. and SubViewports.
  107. .. image:: img/input_event_scene_flow.webp
  108. .. note::
  109. This order doesn't apply to :ref:`Control._gui_input() <class_Control_private_method__gui_input>`, which uses
  110. a different method based on event location or focused Control. GUI **mouse** events also travel
  111. up the scene tree, subject to the :ref:`Control.mouse_filter <class_Control_property_mouse_filter>`
  112. restrictions described above. However, since these events target specific Controls, only direct ancestors of
  113. the targeted Control node receive the event. GUI **keyboard and joypad** events *do not* travel
  114. up the scene tree, and can only be handled by the Control that received them. Otherwise, they will be
  115. propagated as non-GUI events through :ref:`Node._unhandled_input() <class_Node_private_method__unhandled_input>`.
  116. Since Viewports don't send events to other :ref:`SubViewports <class_SubViewport>`, one of the following
  117. methods has to be used:
  118. 1. Use a :ref:`SubViewportContainer <class_SubViewportContainer>`, which automatically
  119. sends events to its child :ref:`SubViewports <class_SubViewport>` after
  120. :ref:`Node._input() <class_Node_private_method__input>` or :ref:`Control._gui_input() <class_Control_private_method__gui_input>`.
  121. 2. Implement event propagation based on the individual requirements.
  122. In accordance with Godot's node-based design, this enables
  123. specialized child nodes to handle and consume particular events, while
  124. their ancestors, and ultimately the scene root, can provide more
  125. generalized behavior if needed.
  126. Anatomy of an InputEvent
  127. ------------------------
  128. :ref:`InputEvent <class_InputEvent>` is just a base built-in type, it does not represent
  129. anything and only contains some basic information, such as event ID
  130. (which is increased for each event), device index, etc.
  131. There are several specialized types of InputEvent, described in the table below:
  132. +-------------------------------------------------------------------+-----------------------------------------+
  133. | Event | Description |
  134. +-------------------------------------------------------------------+-----------------------------------------+
  135. | :ref:`InputEvent <class_InputEvent>` | Empty Input Event. |
  136. +-------------------------------------------------------------------+-----------------------------------------+
  137. | :ref:`InputEventKey <class_InputEventKey>` | Contains a keycode and Unicode value, |
  138. | | as well as modifiers. |
  139. +-------------------------------------------------------------------+-----------------------------------------+
  140. | :ref:`InputEventMouseButton <class_InputEventMouseButton>` | Contains click information, such as |
  141. | | button, modifiers, etc. |
  142. +-------------------------------------------------------------------+-----------------------------------------+
  143. | :ref:`InputEventMouseMotion <class_InputEventMouseMotion>` | Contains motion information, such as |
  144. | | relative and absolute positions and |
  145. | | speed. |
  146. +-------------------------------------------------------------------+-----------------------------------------+
  147. | :ref:`InputEventJoypadMotion <class_InputEventJoypadMotion>` | Contains Joystick/Joypad analog axis |
  148. | | information. |
  149. +-------------------------------------------------------------------+-----------------------------------------+
  150. | :ref:`InputEventJoypadButton <class_InputEventJoypadButton>` | Contains Joystick/Joypad button |
  151. | | information. |
  152. +-------------------------------------------------------------------+-----------------------------------------+
  153. | :ref:`InputEventScreenTouch <class_InputEventScreenTouch>` | Contains multi-touch press/release |
  154. | | information. (only available on mobile |
  155. | | devices) |
  156. +-------------------------------------------------------------------+-----------------------------------------+
  157. | :ref:`InputEventScreenDrag <class_InputEventScreenDrag>` | Contains multi-touch drag information. |
  158. | | (only available on mobile devices) |
  159. +-------------------------------------------------------------------+-----------------------------------------+
  160. | :ref:`InputEventMagnifyGesture <class_InputEventMagnifyGesture>` | Contains a position, a factor as well |
  161. | | as modifiers. |
  162. +-------------------------------------------------------------------+-----------------------------------------+
  163. | :ref:`InputEventPanGesture <class_InputEventPanGesture>` | Contains a position, a delta as well as |
  164. | | modifiers. |
  165. +-------------------------------------------------------------------+-----------------------------------------+
  166. | :ref:`InputEventMIDI <class_InputEventMIDI>` | Contains MIDI-related information. |
  167. +-------------------------------------------------------------------+-----------------------------------------+
  168. | :ref:`InputEventShortcut <class_InputEventShortcut>` | Contains a shortcut. |
  169. +-------------------------------------------------------------------+-----------------------------------------+
  170. | :ref:`InputEventAction <class_InputEventAction>` | Contains a generic action. These events |
  171. | | are often generated by the programmer |
  172. | | as feedback. (more on this below) |
  173. +-------------------------------------------------------------------+-----------------------------------------+
  174. Input actions
  175. -------------
  176. Input actions are a grouping of zero or more InputEvents into a commonly
  177. understood title (for example, the default "ui_left" action grouping both joypad-left input and a keyboard's left arrow key). They are not required to represent an
  178. InputEvent but are useful because they abstract various inputs when
  179. programming the game logic.
  180. This allows for:
  181. - The same code to work on different devices with different inputs (e.g.,
  182. keyboard on PC, Joypad on console).
  183. - Input to be reconfigured at runtime.
  184. - Actions to be triggered programmatically at runtime.
  185. Actions can be created from the Project Settings menu in the **Input Map**
  186. tab and assigned input events.
  187. Any event has the methods :ref:`InputEvent.is_action() <class_InputEvent_method_is_action>`,
  188. :ref:`InputEvent.is_pressed() <class_InputEvent_method_is_pressed>` and :ref:`InputEvent.is_echo() <class_InputEvent_method_is_echo>`.
  189. Alternatively, it may be desired to supply the game back with an action
  190. from the game code (a good example of this is detecting gestures).
  191. The Input singleton has a method for this:
  192. :ref:`Input.parse_input_event() <class_input_method_parse_input_event>`. You would normally use it like this:
  193. .. tabs::
  194. .. code-tab:: gdscript GDScript
  195. var ev = InputEventAction.new()
  196. # Set as ui_left, pressed.
  197. ev.action = "ui_left"
  198. ev.pressed = true
  199. # Feedback.
  200. Input.parse_input_event(ev)
  201. .. code-tab:: csharp
  202. var ev = new InputEventAction();
  203. // Set as ui_left, pressed.
  204. ev.Action = "ui_left";
  205. ev.Pressed = true;
  206. // Feedback.
  207. Input.ParseInputEvent(ev);
  208. .. seealso::
  209. See :ref:`doc_first_3d_game_input_actions` for a tutorial on adding input
  210. actions in the project settings.
  211. InputMap
  212. --------
  213. Customizing and re-mapping input from code is often desired. If your
  214. whole workflow depends on actions, the :ref:`InputMap <class_InputMap>` singleton is
  215. ideal for reassigning or creating different actions at runtime. This
  216. singleton is not saved (must be modified manually) and its state is run
  217. from the project settings (project.godot). So any dynamic system of this
  218. type needs to store settings in the way the programmer best sees fit.