See all cheatsheets

Input Cheatsheet

Input cheatsheet

Godot has a powerful input-handling system for creating all sorts of games and applications. It's even used in the Godot editor itself!
This cheat sheet recaps essential concepts and good practices for handling input in Godot. Check out the Godot input guide for an overview of input in Godot.
  • The two ways to handle input

    Godot's input system has two main APIs:
    1. The Input singleton for simple input checks. It's available anywhere in your code and is great for keeping gameplay-related input checks in your game loop.
    2. The InputEvent system for more control. To use it, you override input methods like _input() and similar methods. It's often used in the user interface, for global shortcuts like pausing the game, or for more complex input handling for applications.
  • Input actions

    You can name multiple keys, buttons, or mouse actions as a single input action in Godot. Then, you can use this action in your code to check for any of the assigned inputs.
  • Input events

    The second input API in Godot revolves around the InputEvent type and virtual methods. Input event objects represent individual inputs like a key press, mouse motion, etc. Godot passes InputEvent objects as arguments to methods like _input() or _unhandled_input() that you override in your scripts.
  • Input event propagation

    Godot calls input methods (_input(), _gui_input(), _unhandled_input(), ...) in a specific order: It first sends input events to _input(), then _gui_input(), _unhandled_input(), and finally _input_event(). This system lets you prioritize input handling based on the node's role in the scene. There are more input methods available, but these are the most common.
    For each method, Godot iterates through nodes in a reverse tree, depth-first order, and calls the method if the node overrides it.
  • Control nodes and input handling

    Control nodes consume input events differently from other nodes. They can catch inputs based on keyboard focus and drawing order:
    • The focused Control node receives keyboard and gamepad inputs first.
    • Control nodes rendered in front of others catch mouse clicks in priority.
    You can change this behavior using properties like Control.mouse_filter and Control.focus_mode.
  • Creating an input action in the editor

    To create an input action in Godot:
    1. Open the project settings.
    2. Navigate to the Input Map tab.
    3. Type a name for the action and press Add.
    4. Assign keys, buttons, or mouse actions to the action by clicking the + button on the right.
    You can then use the input action in your code as a string.
  • Listening to input using input actions

    Use the Input class to check if any key or button of an input action is pressed:
    if Input.is_action_pressed("move_right"):
    	velocity.x = speed
    
  • Listening to input actions that trigger once

    For actions that should trigger once, use Input.is_action_just_pressed(), and for released actions, use Input.is_action_released(). They return true only on the frame in which the action changes state.
    if Input.is_action_just_pressed("jump"):
    	velocity.y = -jump_strength
    
  • Creating input actions in code

    Use the InputMap singleton to create and modify input actions in code:
    1. Add an action name to the input map.
    2. Create an InputEvent object representing the input.
    3. Assign the input event to the action.
    InputMap.add_action("shoot")
    var event_space := InputEventKey.new()
    event_space.physical_keycode = KEY_SPACE
    InputMap.action_add_event("shoot", event_space)
    
    This is useful for plugins, among other things. You can insert input actions required by your plugin when users install it and remove them when the plugin is disabled.
  • Erasing input actions in code

    To erase an input action, use InputMap.erase_action():
    InputMap.erase_action("shoot")
    
    This is useful for cleaning up input actions registered in a plugin.
  • Modifying input actions in code

    You can modify input actions in code by adding or removing input events. The following example erases all events for the "shoot" action and adds a new event:
    InputMap.action_erase_events("shoot")
    var click_event := InputEventMouseButton.new()
    click_event.button_index = MOUSE_BUTTON_LEFT
    InputMap.action_add_event("shoot", click_event)
    
    This is great for letting the player remap inputs and for offering multiple input schemes.
  • Listening to input events with _input()

    Override the _input(), _unhandled_input(), or similar virtual input methods in scripts to receive and handle input events individually. For example, to toggle fullscreen when pressing f11:
    func _input(event: InputEvent) -> void:
    	if event is InputEventKey:
    		if event.scancode == KEY_F11 and event.pressed:
    			toggle_fullscreen()
    
  • Virtual input methods for input events

    Essential virtual input methods in Godot include:
    • _input() for general input events. This takes priority over all other input methods, so it's good for commands like pausing the game or opening the main menu.
    • _gui_input() for Control nodes.
    • _unhandled_input() for unhandled inputs. This is a good default for gameplay-related inputs.
    • _input_event() for 2D collision objects. It reports mouse and touch inputs over a collision shape.
    More input methods are available for applications and more advanced needs, but the four above are the most common in games.
  • The different types of input events

    Godot provides various InputEvent types, including:
    • InputEventKey for keyboard keys.
    • InputEventMouseButton for mouse buttons and basic touch input.
    • InputEventMouseMotion for mouse movements.
    • InputEventJoypadButton for gamepad buttons.
    • InputEventJoypadMotion for gamepad analog stick motions.
    You can check the type of an InputEvent object using the is keyword in GDScript and then access its properties.
  • Consuming input events

    To consume an input event and prevent it from propagating to other nodes, call Viewport.set_input_as_handled():
    func _input(event: InputEvent) -> void:
    	if event.is_action_pressed("cancel"):
    		close_menu()
    		get_viewport().set_input_as_handled()
    
  • Using input actions with virtual input methods

    You can use input actions in virtual input methods like _unhandled_input():
    func _input(event: InputEvent) -> void:
    	if event.is_action_pressed("quick_save"):
    		SaveGame.quick_save()
    
  • Favor unhandled input for gameplay

    For gameplay inputs, when using the InputEvent system, favor using _unhandled_input(). This method is called after _input() and _gui_input(), so it ensures gameplay actions don't happen behind an open menu or dialog, for example.
    func _unhandled_input(event: InputEvent) -> void:
    	if event.is_action_pressed("cancel"):
    		cancel_interaction()
    
  • Control nodes consuming mouse input

    Some Control nodes like Button or ColorRect automatically consume mouse input events by default. This ensures that clicking a piece of the user interface does not also interact with the game world behind it.
    You can change this behavior using the mouse_filter property to let clicks pass through to nodes behind them:
    extends ColorRect
    
    func _ready() -> void:
    	mouse_filter = Control.MOUSE_FILTER_IGNORE
    
  • Using _gui_input() for UI elements

    In Control nodes, override _gui_input() to detect and handle UI-specific input events. The function reports input events like mouse clicks within the node's bounding box and key presses while the node has keyboard focus.
    A good example of where you'd use _gui_input() is a grid-based inventory system where you drag items around and stack them:
    extends Panel
    
    var held_item: Item = null
    
    func _gui_input(event: InputEvent) -> void:
        if event.is_action_pressed("mouse_left"):
    		if held_item != null:
    			place_held_item()
    		else:
    			pick_up_item()
    
  • Connecting gui_input signals

    You can connect the gui_input signal of a Control node to a method in the node's script or, better, to a method in a separate script. All input events detected by the Control node are sent to the connected method. This allows grouping input handling for multiple Control nodes in a single script.
    Here's an example with a menu that contains multiple generated buttons. We want the selected buttons to cycle. Pressing down when the last button is selected should select the first button and vice-versa. We connect the gui_input signal of each button to a method in the menu script:
    extends Panel
    
    var _selected_item_index := 0
    var _item_count := 3
    
    
    func _ready() -> void:
    	for index: int in _item_count:
    		var button := Button.new()
    		button.text = "Item " + str(index)
    		add_child(button)
    		button.gui_input.connect(_on_button_input)
    
    
    func _on_button_input(event: InputEvent) -> void:
    	if event.is_action_pressed("cancel"):
    		button.release_focus()
    		_selected_item_index = -1
    		return
    
    	var direction := 0
    	elif event.is_action_pressed("ui_up"):
    		direction = -1
    	elif event.is_action_pressed("ui_down"):
    		direction = 1
    	_selected_item_index = wrapi(_selected_item_index + direction, 0, _item_count - 1)
    	get_child(_selected_item_index).grab_focus()
    
  • Generating input events programmatically

    You can generate input events programmatically by calling Input.parse_input_event() and passing an InputEvent object. This is useful for simulating input events or for creating custom input events.
    This example simulates pressing space:
    var event := InputEventKey.new()
    event.scancode = KEY_SPACE
    event.pressed = true
    Input.parse_input_event(event)
    
    You can also use this to create custom input events for your game or application, like custom touch gestures.
  • Moving the mouse cursor

    You can move the mouse cursor programmatically by calling Viewport.warp_mouse(), Input.warp_mouse(), or Control.warp_mouse(). You can use these methods for mechanics, like wrapping the mouse cursor around the screen.
    This example warps the mouse cursor to the center of the game window (or the screen if the game is fullscreen):
    func _ready() -> void:
    	get_viewport().warp_mouse(get_viewport().get_visible_rect().size / 2)