Up to date

This page is up to date for Godot 4.1. If you still find outdated information, please open an issue.

Input examples

Introduction

In this tutorial, you’ll learn how to use Godot’s InputEvent system to capture player input. There are many different types of input your game may use - keyboard, gamepad, mouse, etc. - and many different ways to turn those inputs into actions in your game. This document will show you some of the most common scenarios, which you can use as starting points for your own projects.

Note

For a detailed overview of how Godot’s input event system works, see Using InputEvent.

Events versus polling

Sometimes you want your game to respond to a certain input event - pressing the “jump” button, for example. For other situations, you might want something to 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 input event occurs. In the second case, Godot provides the Input singleton, which you can use to query the state of an input.

Examples:

GDScriptC#

  1. func _input(event):
  2. if event.is_action_pressed("jump"):
  3. jump()
  4. func _physics_process(delta):
  5. if Input.is_action_pressed("move_right"):
  6. # Move as long as the key/button is pressed.
  7. position.x += speed * delta
  1. public override void _Input(InputEvent @event)
  2. {
  3. if (@event.IsActionPressed("jump"))
  4. {
  5. Jump();
  6. }
  7. }
  8. public override void _PhysicsProcess(double delta)
  9. {
  10. if (Input.IsActionPressed("move_right"))
  11. {
  12. // Move as long as the key/button is pressed.
  13. position.X += speed * (float)delta;
  14. }
  15. }

This gives you the flexibility to mix-and-match the type of input processing you do.

For the remainder of this tutorial, we’ll focus on capturing individual events in _input().

Input events

Input events are objects that inherit from InputEvent. Depending on the event type, the object will contain specific properties related to that event. To see what events actually look like, add a Node and attach the following script:

GDScriptC#

  1. extends Node
  2. func _input(event):
  3. print(event.as_text())
  1. using Godot;
  2. public partial class Node : Godot.Node
  3. {
  4. public override void _Input(InputEvent @event)
  5. {
  6. GD.Print(@event.AsText());
  7. }
  8. }

As you press keys, move the mouse, and perform other inputs, you’ll see each event scroll by in the output window. Here’s an example of the output:

  1. A
  2. Mouse motion at position ((971, 5)) with velocity ((0, 0))
  3. Right Mouse Button
  4. Mouse motion at position ((870, 243)) with velocity ((0.454937, -0.454937))
  5. Left Mouse Button
  6. Mouse Wheel Up
  7. A
  8. B
  9. Shift
  10. Alt+Shift
  11. Alt
  12. Shift+T
  13. 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 of input. Key events are even printed as their key symbols. For example, let’s consider InputEventMouseButton. It inherits from the following classes:

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 that doesn’t contain it - calling position on InputEventKey for example. To avoid this, make sure to test the event type first:

GDScriptC#

  1. func _input(event):
  2. if event is InputEventMouseButton:
  3. print("mouse button event at ", event.position)
  1. public override void _Input(InputEvent @event)
  2. {
  3. if (@event is InputEventMouseButton mouseEvent)
  4. {
  5. GD.Print("mouse button event at ", mouseEvent.Position);
  6. }
  7. }

InputMap

The InputMap is the most flexible way to handle a variety of inputs. You use this by creating named input actions, to which you 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 select the InputMap tab:

../../_images/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 of the action you’re looking for:

GDScriptC#

  1. func _input(event):
  2. if event.is_action_pressed("my_action"):
  3. print("my_action occurred!")
  1. public override void _Input(InputEvent @event)
  2. {
  3. if (@event.IsActionPressed("my_action"))
  4. {
  5. GD.Print("my_action occurred!");
  6. }
  7. }

Keyboard events

Keyboard events are captured in InputEventKey. While it’s recommended to use input actions instead, there may be cases where you want to specifically look at key events. For this example, let’s check for the T:

GDScriptC#

  1. func _input(event):
  2. if event is InputEventKey and event.pressed:
  3. if event.keycode == KEY_T:
  4. print("T was pressed")
  1. public override void _Input(InputEvent @event)
  2. {
  3. if (@event is InputEventKey keyEvent && keyEvent.Pressed)
  4. {
  5. if (keyEvent.Keycode == Key.T)
  6. {
  7. GD.Print("T was pressed");
  8. }
  9. }
  10. }

Tip

See @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 for more information.

Keyboard modifiers

Modifier properties are inherited from InputEventWithModifiers. This allows you to check for modifier combinations using boolean properties. Let’s imagine you want one thing to happen when the T is pressed, but something different when it’s Shift + T:

GDScriptC#

  1. func _input(event):
  2. if event is InputEventKey and event.pressed:
  3. if event.keycode == KEY_T:
  4. if event.shift_pressed:
  5. print("Shift+T was pressed")
  6. else:
  7. print("T was pressed")
  1. public override void _Input(InputEvent @event)
  2. {
  3. if (@event is InputEventKey keyEvent && keyEvent.Pressed)
  4. {
  5. switch (keyEvent.Keycode)
  6. {
  7. case Key.T:
  8. GD.Print(keyEvent.ShiftPressed ? "Shift+T was pressed" : "T was pressed");
  9. break;
  10. }
  11. }
  12. }

Tip

See @GlobalScope_Key for a list of keycode constants.

Mouse events

Mouse events stem from the InputEventMouse class, and are separated into two types: InputEventMouseButton and InputEventMouseMotion. Note that this means that all mouse events will contain a position property.

Mouse buttons

Capturing mouse buttons is very similar to handling key events. @GlobalScope_MouseButton contains a list of MOUSE_BUTTON_* constants for each possible button, which will be reported in the event’s button_index property. Note that the scrollwheel also counts as a button - two buttons, to be precise, with both MOUSE_BUTTON_WHEEL_UP and MOUSE_BUTTON_WHEEL_DOWN being separate events.

GDScriptC#

  1. func _input(event):
  2. if event is InputEventMouseButton:
  3. if event.button_index == MOUSE_BUTTON_LEFT and event.pressed:
  4. print("Left button was clicked at ", event.position)
  5. if event.button_index == MOUSE_BUTTON_WHEEL_UP and event.pressed:
  6. print("Wheel up")
  1. public override void _Input(InputEvent @event)
  2. {
  3. if (@event is InputEventMouseButton mouseEvent && mouseEvent.Pressed)
  4. {
  5. switch (mouseEvent.ButtonIndex)
  6. {
  7. case MouseButton.Left:
  8. GD.Print($"Left button was clicked at {mouseEvent.Position}");
  9. break;
  10. case MouseButton.WheelUp:
  11. GD.Print("Wheel up");
  12. break;
  13. }
  14. }
  15. }

Mouse motion

InputEventMouseMotion events occur whenever the 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 Sprite2D node:

GDScriptC#

  1. extends Node
  2. var dragging = false
  3. var click_radius = 32 # Size of the sprite.
  4. func _input(event):
  5. if event is InputEventMouseButton and event.button_index == MOUSE_BUTTON_LEFT:
  6. if (event.position - $Sprite2D.position).length() < click_radius:
  7. # Start dragging if the click is on the sprite.
  8. if not dragging and event.pressed:
  9. dragging = true
  10. # Stop dragging if the button is released.
  11. if dragging and not event.pressed:
  12. dragging = false
  13. if event is InputEventMouseMotion and dragging:
  14. # While dragging, move the sprite with the mouse.
  15. $Sprite2D.position = event.position
  1. using Godot;
  2. public partial class MyNode2D : Node2D
  3. {
  4. private bool _dragging = false;
  5. private int _clickRadius = 32; // Size of the sprite.
  6. public override void _Input(InputEvent @event)
  7. {
  8. Sprite2D sprite = GetNodeOrNull<Sprite2D>("Sprite2D");
  9. if (sprite == null)
  10. {
  11. return; // No suitable node was found.
  12. }
  13. if (@event is InputEventMouseButton mouseEvent && mouseEvent.ButtonIndex == MouseButton.Left)
  14. {
  15. if ((mouseEvent.Position - sprite.Position).Length() < _clickRadius)
  16. {
  17. // Start dragging if the click is on the sprite.
  18. if (!_dragging && mouseEvent.Pressed)
  19. {
  20. _dragging = true;
  21. }
  22. }
  23. // Stop dragging if the button is released.
  24. if (_dragging && !mouseEvent.Pressed)
  25. {
  26. _dragging = false;
  27. }
  28. }
  29. else
  30. {
  31. if (@event is InputEventMouseMotion motionEvent && _dragging)
  32. {
  33. // While dragging, move the sprite with the mouse.
  34. sprite.Position = motionEvent.Position;
  35. }
  36. }
  37. }
  38. }

Touch events

If you are using a touchscreen device, you can generate touch events. InputEventScreenTouch is equivalent to a mouse click event, and 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.