diff --git a/tutorials/inputs/inputevent.rst b/tutorials/inputs/inputevent.rst index b1e2fbf65..780a08ae8 100644 --- a/tutorials/inputs/inputevent.rst +++ b/tutorials/inputs/inputevent.rst @@ -69,12 +69,17 @@ received input, in order: .. image:: img/input_event_flow.png -1. First of all, the standard :ref:`Node._input() ` function +1. If the Viewport is embedding Windows, the Viewport tries to interpret the event in its + capability as a Window-Manager (e.g. for resizing or moving Windows). +2. Next if an embedded Window is focused, the event is sent to that Window and processed in + the Windows Viewport. If no embedded Window is focused, The Event is sent to the nodes of + the current viewport in the following order. +3. First of all, the standard :ref:`Node._input() ` function will be called in any node that overrides it (and hasn't disabled input processing with :ref:`Node.set_process_input() `). If any function consumes the event, it can call :ref:`Viewport.set_input_as_handled() `, and the event will not spread any more. This ensures that you can filter all events of interest, even before the GUI. For gameplay input, :ref:`Node._unhandled_input() ` is generally a better fit, because it allows the GUI to intercept the events. -2. Second, it will try to feed the input to the GUI, and see if any +4. Second, it will try to feed the input to the GUI, and see if any control can receive it. If so, the :ref:`Control ` will be called via the virtual function :ref:`Control._gui_input() ` and the signal "gui_input" will be emitted (this function is re-implementable by @@ -84,26 +89,52 @@ received input, in order: property to control whether a :ref:`Control ` is notified of mouse events via :ref:`Control._gui_input() ` callback, and whether these events are propagated further. -3. If so far no one consumed the event, the unhandled input callback +5. If so far no one consumed the event, the :ref:`Node._shortcut_input() ` callback + will be called if overridden (and not disabled with + :ref:`Node.set_process_shortcut_input() `). + This happens only for :ref:`InputEventKey `, + :ref:`InputEventShortcut ` and :ref:`InputEventJoypadButton `. + If any function consumes the event, it can call :ref:`Viewport.set_input_as_handled() `, and the + event will not spread any more. The shortcut input callback is ideal for treating events that are intended as shortcuts. +6. If so far no one consumed the event, the :ref:`Node._unhandled_input() ` callback will be called if overridden (and not disabled with :ref:`Node.set_process_unhandled_input() `). If any function consumes the event, it can call :ref:`Viewport.set_input_as_handled() `, and the 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. -4. If no one wanted the event so far, and a :ref:`Camera3D ` is assigned - to the Viewport with :ref:`Object Picking ` turned on, a ray to the physics world (in the ray direction from - the click) will be cast. (For the root viewport, this can also be enabled in :ref:`Project Settings `.) If this ray hits an object, it will call the - :ref:`CollisionObject._input_event() ` function in the relevant - physics object (bodies receive this callback by default, but areas do +7. If so far no one consumed the event, the :ref:`Node._unhandled_key_input() ` callback + will be called if overridden (and not disabled with + :ref:`Node.set_process_unhandled_key_input() `). + This happens only if the event is a :ref:`InputEventKey `. + If any function consumes the event, it can call :ref:`Viewport.set_input_as_handled() `, and the + event will not spread any more. The unhandled key input callback is ideal for key events. +8. If no one wanted the event so far, and :ref:`Object Picking ` + is turned on, the event is used for object picking. For the root viewport, this can also be + enabled in :ref:`Project Settings `. + In the case of a 3D scene if a :ref:`Camera3D ` is assigned to the Viewport, a ray + to the physics world (in the ray direction from the click) will be cast. If this ray hits an object, + it will call the :ref:`CollisionObject3D._input_event() ` + function in the relevant physics object (bodies receive this callback by default, but areas do not. This can be configured through :ref:`Area3D ` properties). -5. Finally, if the event was unhandled, it will be passed to the next - Viewport in the tree, otherwise it will be ignored. + In the case of a 2D scene, conceptually the same happens with :ref:`CollisionObject2D._input_event() `. -When sending events to all listening nodes within a scene, the viewport -will do so in a reverse depth-first order: Starting with the node at -the bottom of the scene tree, and ending at the root node: +When sending events to its child and descencand nodes, the viewport will do so, as depicted in +the following graphic, in a reverse depth-first order, starting with the node at the bottom of +the scene tree, and ending at the root node. Excluded from this process are embedded Windows +and SubViewports. .. image:: img/input_event_scene_flow.png +This order doesn't apply to :ref:`Control._gui_input() `, which uses +a different method based on event location or focused Control. + +Since Viewports don't send events to other :ref:`SubViewports `, one of the following +methods has to be used: + +1. Use a :ref:`SubViewportContainer `, which automatically + sends events to its child :ref:`SubViewports ` during + :ref:`Node._input() ` and :ref:`Node._unhandled_input() `. +2. Implement event propagation based on the indivitual requirements. + GUI events also travel up the scene tree but, since these events target specific Controls, only direct ancestors of the targeted Control node receive the event. diff --git a/tutorials/rendering/viewports.rst b/tutorials/rendering/viewports.rst index b5e16df8f..ff07fc76a 100644 --- a/tutorials/rendering/viewports.rst +++ b/tutorials/rendering/viewports.rst @@ -38,10 +38,10 @@ Input ----- :ref:`Viewports ` are also responsible for delivering properly adjusted and -scaled input events to all their children nodes. Typically, input is received by the -nearest :ref:`Viewport ` in the tree, but you can set :ref:`Viewports ` not to receive input by checking -'Disable Input' to 'on'; this will allow the next nearest :ref:`Viewport ` in the tree to capture -the input. +scaled input events to their children nodes. By default :ref:`SubViewports ` don't +automatically receive input, unless they receive it from their direct +:ref:`SubViewportContainer ` parent node. In this case, input can be +disabled with the :ref:`Disable Input ` property. .. image:: img/input.png