2023-01-12 20:49:14 +01:00
|
|
|
|
2022-03-18 17:46:08 +01:00
|
|
|
|
|
|
|
Input examples
|
|
|
|
==============
|
|
|
|
|
|
|
|
Introduction
|
|
|
|
------------
|
|
|
|
|
2023-01-12 19:30:47 +01:00
|
|
|
In this tutorial, you'll learn how to use Godot's `InputEvent`
|
2022-03-18 17:46:08 +01:00
|
|
|
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.
|
|
|
|
|
2023-01-12 20:55:57 +01:00
|
|
|
Note:
|
|
|
|
For a detailed overview of how Godot's input event system works,
|
2023-01-12 19:29:11 +01:00
|
|
|
see `doc_inputevent`.
|
2022-03-18 17:46:08 +01:00
|
|
|
|
|
|
|
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,
|
2023-01-12 20:57:31 +01:00
|
|
|
you can use the `input()` function, which will be called whenever an input
|
2023-01-12 19:30:47 +01:00
|
|
|
event occurs. In the second case, Godot provides the `Input`
|
2022-03-18 17:46:08 +01:00
|
|
|
singleton, which you can use to query the state of an input.
|
|
|
|
|
|
|
|
Examples:
|
|
|
|
|
2023-01-12 18:31:02 +01:00
|
|
|
gdscript GDScript
|
2022-03-18 17:46:08 +01:00
|
|
|
|
2023-01-12 18:31:02 +01:00
|
|
|
```
|
2022-03-18 17:46:08 +01:00
|
|
|
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
|
2023-01-12 18:31:02 +01:00
|
|
|
```
|
2022-03-18 17:46:08 +01:00
|
|
|
|
|
|
|
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
|
2023-01-12 20:57:31 +01:00
|
|
|
events in `input()`.
|
2022-03-18 17:46:08 +01:00
|
|
|
|
|
|
|
Input events
|
|
|
|
------------
|
|
|
|
|
2023-01-12 19:30:47 +01:00
|
|
|
Input events are objects that inherit from `InputEvent`.
|
2022-03-18 17:46:08 +01:00
|
|
|
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:
|
|
|
|
|
2023-01-12 18:31:02 +01:00
|
|
|
gdscript GDScript
|
2022-03-18 17:46:08 +01:00
|
|
|
|
2023-01-12 18:31:02 +01:00
|
|
|
```
|
2022-03-18 17:46:08 +01:00
|
|
|
extends Node
|
|
|
|
|
|
|
|
|
|
|
|
func _input(event):
|
|
|
|
print(event.as_text())
|
2023-01-12 18:31:02 +01:00
|
|
|
```
|
2022-03-18 17:46:08 +01:00
|
|
|
|
|
|
|
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:
|
|
|
|
|
2023-01-12 22:00:14 +01:00
|
|
|
```
|
2022-03-18 17:46:08 +01:00
|
|
|
A
|
|
|
|
InputEventMouseMotion : button_mask=0, position=(108, 108), relative=(26, 1), speed=(164.152496, 159.119843), pressure=(0), tilt=(0, 0)
|
|
|
|
InputEventMouseButton : button_index=BUTTON_LEFT, pressed=true, position=(108, 107), button_mask=1, doubleclick=false
|
|
|
|
InputEventMouseButton : button_index=BUTTON_LEFT, pressed=false, position=(108, 107), button_mask=0, doubleclick=false
|
|
|
|
S
|
|
|
|
F
|
|
|
|
Alt
|
|
|
|
InputEventMouseMotion : button_mask=0, position=(108, 107), relative=(0, -1), speed=(164.152496, 159.119843), pressure=(0), tilt=(0, 0)
|
2023-01-12 22:00:14 +01:00
|
|
|
```
|
2022-03-18 17:46:08 +01:00
|
|
|
|
|
|
|
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
|
2023-01-12 19:30:47 +01:00
|
|
|
consider `InputEventMouseButton`.
|
2022-03-18 17:46:08 +01:00
|
|
|
It inherits from the following classes:
|
|
|
|
|
2023-01-12 19:30:47 +01:00
|
|
|
- `InputEvent` - the base class for all input events
|
|
|
|
- `InputEventWithModifiers` - adds the ability to check if modifiers are pressed, such as :kbd:`Shift` or :kbd:`Alt`.
|
2023-01-12 19:43:03 +01:00
|
|
|
- `InputEventMouse` - adds mouse event properties, such as `position`
|
2023-01-12 19:30:47 +01:00
|
|
|
- `InputEventMouseButton` - contains the index of the button that was pressed, whether it was a double-click, etc.
|
2022-03-18 17:46:08 +01:00
|
|
|
|
2023-01-12 21:01:51 +01:00
|
|
|
Tip:
|
|
|
|
It's a good idea to keep the class reference open while you're working
|
2022-03-18 17:46:08 +01:00
|
|
|
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
|
2023-01-12 19:43:03 +01:00
|
|
|
doesn't contain it - calling `position` on `InputEventKey` for example. To
|
2022-03-18 17:46:08 +01:00
|
|
|
avoid this, make sure to test the event type first:
|
|
|
|
|
2023-01-12 18:31:02 +01:00
|
|
|
gdscript GDScript
|
2022-03-18 17:46:08 +01:00
|
|
|
|
2023-01-12 18:31:02 +01:00
|
|
|
```
|
2022-03-18 17:46:08 +01:00
|
|
|
func _input(event):
|
|
|
|
if event is InputEventMouseButton:
|
|
|
|
print("mouse button event at ", event.position)
|
2023-01-12 18:31:02 +01:00
|
|
|
```
|
2022-03-18 17:46:08 +01:00
|
|
|
|
|
|
|
InputMap
|
|
|
|
--------
|
|
|
|
|
2023-01-12 19:30:47 +01:00
|
|
|
The `InputMap` is the most flexible way to handle a
|
2022-03-18 17:46:08 +01:00
|
|
|
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.
|
|
|
|
A new Godot project includes a number of default actions already defined. To
|
|
|
|
see them, and to add your own, open Project -> Project Settings and select
|
|
|
|
the InputMap tab:
|
|
|
|
|
2023-01-12 20:16:00 +01:00
|
|
|
![](img/inputs_inputmap.png)
|
2022-03-18 17:46:08 +01:00
|
|
|
|
|
|
|
Capturing actions
|
|
|
|
~~~~~~~~~~~~~~~~~
|
|
|
|
|
|
|
|
Once you've defined your actions, you can process them in your scripts using
|
2023-01-12 19:43:03 +01:00
|
|
|
`is_action_pressed()` and `is_action_released()` by passing the name of
|
2022-03-18 17:46:08 +01:00
|
|
|
the action you're looking for:
|
|
|
|
|
2023-01-12 18:31:02 +01:00
|
|
|
gdscript GDScript
|
2022-03-18 17:46:08 +01:00
|
|
|
|
2023-01-12 18:31:02 +01:00
|
|
|
```
|
2022-03-18 17:46:08 +01:00
|
|
|
func _input(event):
|
|
|
|
if event.is_action_pressed("my_action"):
|
|
|
|
print("my_action occurred!")
|
2023-01-12 18:31:02 +01:00
|
|
|
```
|
2022-03-18 17:46:08 +01:00
|
|
|
|
|
|
|
Keyboard events
|
|
|
|
---------------
|
|
|
|
|
2023-01-12 19:30:47 +01:00
|
|
|
Keyboard events are captured in `InputEventKey`.
|
2022-03-18 17:46:08 +01:00
|
|
|
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 :kbd:`T`:
|
|
|
|
|
2023-01-12 18:31:02 +01:00
|
|
|
gdscript GDScript
|
2022-03-18 17:46:08 +01:00
|
|
|
|
2023-01-12 18:31:02 +01:00
|
|
|
```
|
2022-03-18 17:46:08 +01:00
|
|
|
func _input(event):
|
|
|
|
if event is InputEventKey and event.pressed:
|
|
|
|
if event.scancode == KEY_T:
|
|
|
|
print("T was pressed")
|
2023-01-12 18:31:02 +01:00
|
|
|
```
|
2022-03-18 17:46:08 +01:00
|
|
|
|
2023-01-12 21:01:51 +01:00
|
|
|
Tip:
|
|
|
|
See `@GlobalScope_KeyList ( enum_@GlobalScope_KeyList )` for a list of scancode
|
2022-03-18 17:46:08 +01:00
|
|
|
constants.
|
|
|
|
|
2023-01-12 20:55:57 +01:00
|
|
|
Warning:
|
|
|
|
|
2022-03-18 17:46:08 +01:00
|
|
|
|
|
|
|
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
|
2023-01-12 20:39:50 +01:00
|
|
|
`this Gamedev Stack Exchange question ( https://gamedev.stackexchange.com/a/109002 )`
|
2022-03-18 17:46:08 +01:00
|
|
|
for more information.
|
|
|
|
|
|
|
|
Keyboard modifiers
|
|
|
|
~~~~~~~~~~~~~~~~~~
|
|
|
|
|
|
|
|
Modifier properties are inherited from
|
2023-01-12 19:30:47 +01:00
|
|
|
`InputEventWithModifiers`. This allows
|
2022-03-18 17:46:08 +01:00
|
|
|
you to check for modifier combinations using boolean properties. Let's imagine
|
|
|
|
you want one thing to happen when the :kbd:`T` is pressed, but something
|
|
|
|
different when it's :kbd:`Shift + T`:
|
|
|
|
|
2023-01-12 18:31:02 +01:00
|
|
|
gdscript GDScript
|
2022-03-18 17:46:08 +01:00
|
|
|
|
2023-01-12 18:31:02 +01:00
|
|
|
```
|
2022-03-18 17:46:08 +01:00
|
|
|
func _input(event):
|
|
|
|
if event is InputEventKey and event.pressed:
|
|
|
|
if event.scancode == KEY_T:
|
|
|
|
if event.shift:
|
|
|
|
print("Shift+T was pressed")
|
|
|
|
else:
|
|
|
|
print("T was pressed")
|
2023-01-12 18:31:02 +01:00
|
|
|
```
|
2022-03-18 17:46:08 +01:00
|
|
|
|
2023-01-12 21:01:51 +01:00
|
|
|
Tip:
|
|
|
|
See `@GlobalScope_KeyList ( enum_@GlobalScope_KeyList )` for a list of scancode
|
2022-03-18 17:46:08 +01:00
|
|
|
constants.
|
|
|
|
|
|
|
|
Mouse events
|
|
|
|
------------
|
|
|
|
|
2023-01-12 19:30:47 +01:00
|
|
|
Mouse events stem from the `InputEventMouse` class, and
|
|
|
|
are separated into two types: `InputEventMouseButton`
|
|
|
|
and `InputEventMouseMotion`. Note that this
|
2023-01-12 19:43:03 +01:00
|
|
|
means that all mouse events will contain a `position` property.
|
2022-03-18 17:46:08 +01:00
|
|
|
|
|
|
|
Mouse buttons
|
|
|
|
~~~~~~~~~~~~~
|
|
|
|
|
2023-01-12 20:47:54 +01:00
|
|
|
Capturing mouse buttons is very similar to handling key events. `@GlobalScope_ButtonList ( enum_@GlobalScope_ButtonList )`
|
2023-01-12 19:43:03 +01:00
|
|
|
contains a list of `BUTTON_*` constants for each possible button, which will
|
|
|
|
be reported in the event's `button_index` property. Note that the scrollwheel
|
2022-03-18 17:46:08 +01:00
|
|
|
also counts as a button - two buttons, to be precise, with both
|
2023-01-12 19:43:03 +01:00
|
|
|
`BUTTON_WHEEL_UP` and `BUTTON_WHEEL_DOWN` being separate events.
|
2022-03-18 17:46:08 +01:00
|
|
|
|
2023-01-12 18:31:02 +01:00
|
|
|
gdscript GDScript
|
2022-03-18 17:46:08 +01:00
|
|
|
|
2023-01-12 18:31:02 +01:00
|
|
|
```
|
2022-03-18 17:46:08 +01:00
|
|
|
func _input(event):
|
|
|
|
if event is InputEventMouseButton:
|
|
|
|
if event.button_index == BUTTON_LEFT and event.pressed:
|
|
|
|
print("Left button was clicked at ", event.position)
|
|
|
|
if event.button_index == BUTTON_WHEEL_UP and event.pressed:
|
|
|
|
print("Wheel up")
|
2023-01-12 18:31:02 +01:00
|
|
|
```
|
2022-03-18 17:46:08 +01:00
|
|
|
|
|
|
|
Mouse motion
|
|
|
|
~~~~~~~~~~~~
|
|
|
|
|
2023-01-12 19:30:47 +01:00
|
|
|
`InputEventMouseMotion` events occur whenever
|
2023-01-12 19:43:03 +01:00
|
|
|
the mouse moves. You can find the move's distance with the `relative`
|
2022-03-18 17:46:08 +01:00
|
|
|
property.
|
|
|
|
|
2023-01-12 19:30:47 +01:00
|
|
|
Here's an example using mouse events to drag-and-drop a `Sprite`
|
2022-03-18 17:46:08 +01:00
|
|
|
node:
|
|
|
|
|
2023-01-12 18:31:02 +01:00
|
|
|
gdscript GDScript
|
2022-03-18 17:46:08 +01:00
|
|
|
|
2023-01-12 18:31:02 +01:00
|
|
|
```
|
2022-03-18 17:46:08 +01:00
|
|
|
extends Node
|
|
|
|
|
|
|
|
|
|
|
|
var dragging = false
|
|
|
|
var click_radius = 32 # Size of the sprite.
|
|
|
|
|
|
|
|
|
|
|
|
func _input(event):
|
|
|
|
if event is InputEventMouseButton and event.button_index == BUTTON_LEFT:
|
2023-01-12 20:47:54 +01:00
|
|
|
if (event.position - $Sprite.position).length() ( click_radius:
|
2022-03-18 17:46:08 +01:00
|
|
|
# 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.
|
|
|
|
$Sprite.position = event.position
|
2023-01-12 18:31:02 +01:00
|
|
|
```
|
2022-03-18 17:46:08 +01:00
|
|
|
|
|
|
|
Touch events
|
|
|
|
------------
|
|
|
|
|
|
|
|
If you are using a touchscreen device, you can generate touch events.
|
2023-01-12 19:30:47 +01:00
|
|
|
`InputEventScreenTouch` is equivalent to
|
|
|
|
a mouse click event, and `InputEventScreenDrag`
|
2022-03-18 17:46:08 +01:00
|
|
|
works much the same as mouse motion.
|
|
|
|
|
2023-01-12 21:01:51 +01:00
|
|
|
Tip:
|
|
|
|
To test your touch events on a non-touchscreen device, open Project
|
2022-03-18 17:46:08 +01:00
|
|
|
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.
|