| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410 | .. _doc_input_examples:Input examples==============Introduction------------In this tutorial, you'll learn how to use Godot's :ref:`InputEvent <class_InputEvent>`system to capture player input. There are many different types of input yourgame may use - keyboard, gamepad, mouse, etc. - and many different ways toturn those inputs into actions in your game. This document will show you someof the most common scenarios, which you can use as starting points for yourown projects... note:: For a detailed overview of how Godot's input event system works,          see :ref:`doc_inputevent`.Events versus polling---------------------Sometimes you want your game to respond to a certain input event - pressingthe "jump" button, for example. For other situations, you might want somethingto happen as long as a key is pressed, such as movement. In the first case,you can use the ``_input()`` function, which will be called whenever an inputevent occurs. In the second case, Godot provides the :ref:`Input <class_Input>`singleton, which you can use to query the state of an input.Examples:.. tabs:: .. code-tab:: gdscript GDScript    func _input(event):        if event.is_action_pressed("jump"):            jump()    func _physics_process(delta):        if Input.is_action_pressed("move_right"):            # Move as long as the key/button is pressed.            position.x += speed * delta .. code-tab:: csharp    public override void _Input(InputEvent @event)    {        if (@event.IsActionPressed("jump"))        {            Jump();        }    }    public override void _PhysicsProcess(double delta)    {        if (Input.IsActionPressed("move_right"))        {            // Move as long as the key/button is pressed.            position.X += speed * (float)delta;        }    }This gives you the flexibility to mix-and-match the type of input processingyou do.For the remainder of this tutorial, we'll focus on capturing individualevents in ``_input()``.Input events------------Input events are objects that inherit from :ref:`InputEvent <class_InputEvent>`.Depending on the event type, the object will contain specific propertiesrelated to that event. To see what events actually look like, add a Node andattach the following script:.. tabs:: .. code-tab:: gdscript GDScript    extends Node    func _input(event):        print(event.as_text()) .. code-tab:: csharp    using Godot;    public partial class Node : Godot.Node    {        public override void _Input(InputEvent @event)        {            GD.Print(@event.AsText());        }    }As you press keys, move the mouse, and perform other inputs, you'll see eachevent scroll by in the output window. Here's an example of the output:::    A    Mouse motion at position ((971, 5)) with velocity ((0, 0))    Right Mouse Button    Mouse motion at position ((870, 243)) with velocity ((0.454937, -0.454937))    Left Mouse Button    Mouse Wheel Up    A    B    Shift    Alt+Shift    Alt    Shift+T    Mouse motion at position ((868, 242)) with velocity ((-2.134768, 2.134768))As you can see, the results are very different for the different types ofinput. Key events are even printed as their key symbols. For example, let'sconsider :ref:`InputEventMouseButton <class_InputEventMouseButton>`.It inherits from the following classes:- :ref:`InputEvent <class_InputEvent>` - the base class for all input events- :ref:`InputEventWithModifiers <class_InputEventWithModifiers>` - adds the ability to check if modifiers are pressed, such as :kbd:`Shift` or :kbd:`Alt`.- :ref:`InputEventMouse <class_InputEventMouse>` - adds mouse event properties, such as ``position``- :ref:`InputEventMouseButton <class_InputEventMouseButton>` - contains the index of the button that was pressed, whether it was a double-click, etc... tip:: It's a good idea to keep the class reference open while you're working        with events so you can check the event type's available properties and        methods.You can encounter errors if you try to access a property on an input type thatdoesn't contain it - calling ``position`` on ``InputEventKey`` for example. Toavoid this, make sure to test the event type first:.. tabs:: .. code-tab:: gdscript GDScript    func _input(event):        if event is InputEventMouseButton:            print("mouse button event at ", event.position) .. code-tab:: csharp    public override void _Input(InputEvent @event)    {        if (@event is InputEventMouseButton mouseEvent)        {            GD.Print("mouse button event at ", mouseEvent.Position);        }    }.. _doc_input_examples_input_map:InputMap--------The :ref:`InputMap <class_InputMap>` is the most flexible way to handle avariety of inputs. You use this by creating named input *actions*, to whichyou can assign any number of input events, such as keypresses or mouse clicks.To see them, and to add your own, open Project -> Project Settings and selectthe InputMap tab:.. image:: img/inputs_inputmap.webp.. tip::    A new Godot project includes a number of default actions already defined.    To see them, turn on ``Show Built-in Actions`` in the InputMap dialog.Capturing actions~~~~~~~~~~~~~~~~~Once you've defined your actions, you can process them in your scripts using``is_action_pressed()`` and ``is_action_released()`` by passing the name ofthe action you're looking for:.. tabs:: .. code-tab:: gdscript GDScript    func _input(event):        if event.is_action_pressed("my_action"):            print("my_action occurred!") .. code-tab:: csharp    public override void _Input(InputEvent @event)    {        if (@event.IsActionPressed("my_action"))        {            GD.Print("my_action occurred!");        }    }Keyboard events---------------Keyboard events are captured in :ref:`InputEventKey <class_InputEventKey>`.While it's recommended to use input actions instead, there may be cases whereyou want to specifically look at key events. For this example, let's check forthe :kbd:`T`:.. tabs:: .. code-tab:: gdscript GDScript    func _input(event):        if event is InputEventKey and event.pressed:            if event.keycode == KEY_T:                print("T was pressed") .. code-tab:: csharp    public override void _Input(InputEvent @event)    {        if (@event is InputEventKey keyEvent && keyEvent.Pressed)        {            if (keyEvent.Keycode == Key.T)            {                GD.Print("T was pressed");            }        }    }.. tip:: See :ref:`@GlobalScope_Key <enum_@GlobalScope_Key>` for a list of keycode        constants... warning::    Due to *keyboard ghosting*, not all key inputs may be registered at a given time    if you press too many keys at once. Due to their location on the keyboard,    certain keys are more prone to ghosting than others. Some keyboards feature    antighosting at a hardware level, but this feature is generally    not present on low-end keyboards and laptop keyboards.    As a result, it's recommended to use a default keyboard layout that is designed to work well    on a keyboard without antighosting. See    `this Gamedev Stack Exchange question <https://gamedev.stackexchange.com/a/109002>`__    for more information.Keyboard modifiers~~~~~~~~~~~~~~~~~~Modifier properties are inherited from:ref:`InputEventWithModifiers <class_InputEventWithModifiers>`. This allowsyou to check for modifier combinations using boolean properties. Let's imagineyou want one thing to happen when the :kbd:`T` is pressed, but somethingdifferent when it's :kbd:`Shift + T`:.. tabs:: .. code-tab:: gdscript GDScript    func _input(event):        if event is InputEventKey and event.pressed:            if event.keycode == KEY_T:                if event.shift_pressed:                    print("Shift+T was pressed")                else:                    print("T was pressed") .. code-tab:: csharp    public override void _Input(InputEvent @event)    {        if (@event is InputEventKey keyEvent && keyEvent.Pressed)        {            switch (keyEvent.Keycode)            {                case Key.T:                    GD.Print(keyEvent.ShiftPressed ? "Shift+T was pressed" : "T was pressed");                    break;            }        }    }.. tip:: See :ref:`@GlobalScope_Key <enum_@GlobalScope_Key>` for a list of keycode        constants.Mouse events------------Mouse events stem from the :ref:`InputEventMouse <class_InputEventMouse>` class, andare separated into two types: :ref:`InputEventMouseButton <class_InputEventMouseButton>`and :ref:`InputEventMouseMotion <class_InputEventMouseMotion>`. Note that thismeans that all mouse events will contain a ``position`` property.Mouse buttons~~~~~~~~~~~~~Capturing mouse buttons is very similar to handling key events. :ref:`@GlobalScope_MouseButton <enum_@GlobalScope_MouseButton>`contains a list of ``MOUSE_BUTTON_*`` constants for each possible button, which willbe reported in the event's ``button_index`` property. Note that the scrollwheelalso counts as a button - two buttons, to be precise, with both``MOUSE_BUTTON_WHEEL_UP`` and ``MOUSE_BUTTON_WHEEL_DOWN`` being separate events... tabs:: .. code-tab:: gdscript GDScript    func _input(event):        if event is InputEventMouseButton:            if event.button_index == MOUSE_BUTTON_LEFT and event.pressed:                print("Left button was clicked at ", event.position)            if event.button_index == MOUSE_BUTTON_WHEEL_UP and event.pressed:                print("Wheel up") .. code-tab:: csharp    public override void _Input(InputEvent @event)    {        if (@event is InputEventMouseButton mouseEvent && mouseEvent.Pressed)        {            switch (mouseEvent.ButtonIndex)            {                case MouseButton.Left:                    GD.Print($"Left button was clicked at {mouseEvent.Position}");                    break;                case MouseButton.WheelUp:                    GD.Print("Wheel up");                    break;            }        }    }Mouse motion~~~~~~~~~~~~:ref:`InputEventMouseMotion <class_InputEventMouseMotion>` events occur wheneverthe mouse moves. You can find the move's distance with the ``relative``property.Here's an example using mouse events to drag-and-drop a :ref:`Sprite2D <class_Sprite2D>`node:.. tabs:: .. code-tab:: gdscript GDScript    extends Node    var dragging = false    var click_radius = 32 # Size of the sprite.    func _input(event):        if event is InputEventMouseButton and event.button_index == MOUSE_BUTTON_LEFT:            if (event.position - $Sprite2D.position).length() < click_radius:                # Start dragging if the click is on the sprite.                if not dragging and event.pressed:                    dragging = true            # Stop dragging if the button is released.            if dragging and not event.pressed:                dragging = false        if event is InputEventMouseMotion and dragging:            # While dragging, move the sprite with the mouse.            $Sprite2D.position = event.position .. code-tab:: csharp    using Godot;    public partial class MyNode2D : Node2D    {        private bool _dragging = false;        private int _clickRadius = 32; // Size of the sprite.        public override void _Input(InputEvent @event)        {            Sprite2D sprite = GetNodeOrNull<Sprite2D>("Sprite2D");            if (sprite == null)            {                return; // No suitable node was found.            }            if (@event is InputEventMouseButton mouseEvent && mouseEvent.ButtonIndex == MouseButton.Left)            {                if ((mouseEvent.Position - sprite.Position).Length() < _clickRadius)                {                    // Start dragging if the click is on the sprite.                    if (!_dragging && mouseEvent.Pressed)                    {                        _dragging = true;                    }                }                // Stop dragging if the button is released.                if (_dragging && !mouseEvent.Pressed)                {                    _dragging = false;                }            }            else            {                if (@event is InputEventMouseMotion motionEvent && _dragging)                {                    // While dragging, move the sprite with the mouse.                    sprite.Position = motionEvent.Position;                }            }        }    }Touch events------------If you are using a touchscreen device, you can generate touch events.:ref:`InputEventScreenTouch <class_InputEventScreenTouch>` is equivalent toa mouse click event, and :ref:`InputEventScreenDrag <class_InputEventScreenDrag>`works much the same as mouse motion... tip:: To test your touch events on a non-touchscreen device, open Project        Settings and go to the "Input Devices/Pointing" section. Enable "Emulate        Touch From Mouse" and your project will interpret mouse clicks and        motion as touch events.
 |