Ver código fonte

Update Input Event Tutorial

Markus Sauermann 2 anos atrás
pai
commit
d2a75723da
2 arquivos alterados com 48 adições e 17 exclusões
  1. 44 13
      tutorials/inputs/inputevent.rst
  2. 4 4
      tutorials/rendering/viewports.rst

+ 44 - 13
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() <class_Node_method__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() <class_Node_method__input>` function
    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>`).
    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
    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() <class_Node_method__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 <class_Control>` will be called via the
    virtual function :ref:`Control._gui_input() <class_Control_method__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 <class_Control>` is notified
    of mouse events via :ref:`Control._gui_input() <class_Control_method__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() <class_Node_method__shortcut_input>` callback
+   will be called if overridden (and not disabled with
+   :ref:`Node.set_process_shortcut_input() <class_Node_method_set_process_shortcut_input>`).
+   This happens only for :ref:`InputEventKey <class_InputEventKey>`,
+   :ref:`InputEventShortcut <class_InputEventShortcut>` and :ref:`InputEventJoypadButton <class_InputEventJoypadButton>`.
+   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 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() <class_Node_method__unhandled_input>` callback
    will be called if overridden (and not disabled with
    :ref:`Node.set_process_unhandled_input() <class_Node_method_set_process_unhandled_input>`).
    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 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 <class_Camera3D>` is assigned
-   to the Viewport with :ref:`Object Picking <class_viewport_property_physics_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 <class_ProjectSettings_property_physics/common/enable_object_picking>`.) If this ray hits an object, it will call the
-   :ref:`CollisionObject._input_event() <class_CollisionObject3D_method__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() <class_Node_method__unhandled_key_input>` callback
+   will be called if overridden (and not disabled with
+   :ref:`Node.set_process_unhandled_key_input() <class_Node_method_set_process_unhandled_key_input>`).
+   This happens only if the event is a :ref:`InputEventKey <class_InputEventKey>`.
+   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 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 <class_viewport_property_physics_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 <class_ProjectSettings_property_physics/common/enable_object_picking>`.
+   In the case of a 3D scene if a :ref:`Camera3D <class_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() <class_CollisionObject3D_method__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 <class_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() <class_CollisionObject2D_method__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() <class_Control_method__gui_input>`, which uses
+a different method based on event location or focused Control.
+
+Since Viewports don't send events to other :ref:`SubViewports <class_SubViewport>`, one of the following
+methods has to be used:
+
+1. Use a :ref:`SubViewportContainer <class_SubViewportContainer>`, which automatically
+   sends events to its child :ref:`SubViewports <class_SubViewport>` during
+   :ref:`Node._input() <class_Node_method__input>` and :ref:`Node._unhandled_input() <class_Node_method__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.
 

+ 4 - 4
tutorials/rendering/viewports.rst

@@ -38,10 +38,10 @@ Input
 -----
 
 :ref:`Viewports <class_Viewport>` 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 <class_Viewport>` in the tree, but you can set :ref:`Viewports <class_Viewport>` not to receive input by checking
-'Disable Input' to 'on'; this will allow the next nearest :ref:`Viewport <class_Viewport>` in the tree to capture
-the input.
+scaled input events to their children nodes. By default :ref:`SubViewports <class_SubViewport>` don't
+automatically receive input, unless they receive it from their direct
+:ref:`SubViewportContainer <class_SubViewportContainer>` parent node. In this case, input can be
+disabled with the :ref:`Disable Input <class_Viewport_property_gui_disable_input>` property.
 
 .. image:: img/input.png