/input-handling
Use when implementing input — InputEvent system, Input Map actions, controllers/gamepads, mouse/touch, action rebinding, and input architecture
$ npx -y skills add jame581/GodotPrompter --skill input-handling --agent claude-codeHow it fires
How this skill gets triggered: by you, by Claude, or both.
- Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
- You can call itInvoke it directly when you want it.
- Slash command
/input-handling
Context preview
The summary Claude sees to decide when to auto-load this skill.
Use when implementing input — InputEvent system, Input Map actions, controllers/gamepads, mouse/touch, action rebinding, and input architecture
SKILL.md
input-handling.SKILL.mdname: input-handling
description: Use when implementing input — InputEvent system, Input Map actions, controllers/gamepads, mouse/touch, action rebinding, and input architecture
Input Handling in Godot 4.3+
All examples target Godot 4.3+ with no deprecated APIs. GDScript is shown first, then C#.
> **Related skills:** **player-controller** for movement driven by input, **godot-ui** for UI input focus and navigation, **save-load** for persisting custom key bindings, **responsive-ui** for touch vs desktop input adaptation, **xr-development** for XR controller and hand tracking input, **mobile-development** for mobile sensors and app lifecycle.
---
1. Core Concepts
Input Flow
Hardware Event (key, mouse, gamepad)
↓
Engine converts to InputEvent
↓
_input() ← raw input, runs first
↓
_shortcut_input() ← for global shortcuts
↓
UI Control nodes ← buttons, sliders consume events
↓
_unhandled_key_input() ← unhandled key-only events
↓
_unhandled_input() ← game input (movement, actions)Where to Handle Input
| Method | Use For | When It Runs | |---------------------------|--------------------------------------------|------------------| | `_input()` | Camera look, global hotkeys | First — before everything | | `_shortcut_input()` | Global shortcuts (pause, screenshot) | After `_input`, before UI | | `_unhandled_key_input()` | Key-only events that UI didn't consume | After UI, keys only | | `_unhandled_input()` | Gameplay actions (jump, attack, interact) | Last — after UI consumes | | `Input.is_action_pressed()` in `_physics_process()` | Continuous movement | N/A — polling, not event-driven |
**Rule of thumb:** Use `_unhandled_input()` for discrete game actions (jump, attack). Use `Input` polling in `_physics_process()` for continuous movement. Use `_input()` only when you need input before UI consumes it (e.g., mouse look).
InputEvent Hierarchy
InputEvent
├── InputEventKey ← keyboard
├── InputEventMouseButton ← mouse clicks
├── InputEventMouseMotion ← mouse movement
├── InputEventJoypadButton ← gamepad buttons
├── InputEventJoypadMotion ← gamepad sticks/triggers
├── InputEventScreenTouch ← touchscreen tap
├── InputEventScreenDrag ← touchscreen drag
├── InputEventAction ← synthetic action events
├── InputEventMIDI ← MIDI devices
└── InputEventGesture ← pinch, pan gestures
├── InputEventMagnifyGesture
└── InputEventPanGesture---
2. Input Map Setup
Define actions in **Project > Project Settings > Input Map** instead of checking raw keycodes. This decouples game logic from specific keys and enables rebinding.
Default Project Actions
Godot ships with `ui_*` actions: `ui_accept`, `ui_cancel`, `ui_left`, `ui_right`, `ui_up`, `ui_down`, etc. These are used by UI controls for keyboard navigation. You can use them for gameplay but creating custom actions is preferred to avoid conflicts.
Adding Actions in Code
Actions can be created at runtime with `InputMap.add_action()` + `InputMap.action_add_event()` — typically in an autoload `_ready()`, guarded by `InputMap.has_action()`. Define actions in the editor Input Map; only add them in code for dynamically generated bindings or mod support.
> See [references/action-rebinding.md](references/action-rebinding.md) for the GDScript and C# snippet.
Recommended Action Names
Use descriptive, game-specific names instead of key names:
| Good | Bad | Why | |---------------------|------------------|--------------------------------------| | `move_left` | `press_a` | Decoupled from physical key | | `attack` | `left_click` | Works for mouse and gamepad | | `interact` | `press_e` | Rebindable without changing logic | | `sprint` | `hold_shift` | Input-agnostic | | `pause` | `press_escape` | Can map to gamepad Start button too |
---
3. Reading Input — Events vs Polling
Event-Driven (Discrete Actions)
Use `_unhandled_input()` for one-shot actions: jump, attack, interact, pause.
GDScript
func _unhandled_input(event: InputEvent) -> void:
if event.is_action_pressed("jump"):
_jump()
get_viewport().set_input_as_handled() # prevent further propagation
if event.is_action_pressed("interact"):
_interact()
if event.is_action_pressed("pause"):
get_tree().paused = not get_tree().paused
get_viewport().set_input_as_handled()C#
public override void _UnhandledInput(InputEvent @event)
{
if (@event.IsActionPressed("jump"))
{
Jump();
GetViewport().SetInputAsHandled();
}
if (@event.IsActionPressed("interact"))
Interact();
if (@event.IsActionPressed("pause"))
{
GetTree().Paused = !GetTree().Paused;
GetViewport().SetInputAsHandled();
}
}Polling (Continuous Input)
Use `Input` singleton in `_physics_process()` for held buttons and analog axes.
GDScript
func _physics_process(delta: float) -> void:
# Movement vector from 4 directional actions
var direction := Input.get_vector("move_left", "move_right", "move_up", "move_down")
velocity = direction * speed
# Check if a button is held
if Input.is_action_pressed("sprint"):
velocity *= 1.5
move_and_slide()C#
public override void _PhysicsProcess(double delta)
{
Vector2 direction = Input.GetVector("move_left", "move_right", "move_up", "move_down");
Velocity = direction * Speed;
if (Input.IsActionPressed("sprint"))
Velocity *= 1.5f;
MoveAndSlide();
}Key Input Methods
| Method | Returns | Use For | |-----------------------------------|---------|--------------------------------------| | `Input.is_action_pressed()` | `bool` | Held buttons (sprint, crouch, fire) | | `Input.is_action_just_pressed()` | `bool` | One-shot triggers (jump, interact) | | `Input.is_action_just_re
Read more
name: input-handling description: Use when implementing input — InputEvent system, Input Map actions, controllers/gamepads, mouse/touch, action rebinding, and input architecture
Input Handling in Godot 4.3+
All examples target Godot 4.3+ with no deprecated APIs. GDScript is shown first, then C#.
> **Related skills:** **player-controller** for movement driven by input, **godot-ui** for UI input focus and navigation, **save-load** for persisting custom key bindings, **responsive-ui** for touch vs desktop input adaptation, **xr-development** for XR controller and hand tracking input, **mobile-development** for mobile sensors and app lifecycle.
---
1. Core Concepts
Input Flow
Hardware Event (key, mouse, gamepad)
↓
Engine converts to InputEvent
↓
_input() ← raw input, runs first
↓
_shortcut_input() ← for global shortcuts
↓
UI Control nodes ← buttons, sliders consume events
↓
_unhandled_key_input() ← unhandled key-only events
↓
_unhandled_input() ← game input (movement, actions)Where to Handle Input
| Method | Use For | When It Runs | |---------------------------|--------------------------------------------|------------------| | `_input()` | Camera look, global hotkeys | First — before everything | | `_shortcut_input()` | Global shortcuts (pause, screenshot) | After `_input`, before UI | | `_unhandled_key_input()` | Key-only events that UI didn't consume | After UI, keys only | | `_unhandled_input()` | Gameplay actions (jump, attack, interact) | Last — after UI consumes | | `Input.is_action_pressed()` in `_physics_process()` | Continuous movement | N/A — polling, not event-driven |
**Rule of thumb:** Use `_unhandled_input()` for discrete game actions (jump, attack). Use `Input` polling in `_physics_process()` for continuous movement. Use `_input()` only when you need input before UI consumes it (e.g., mouse look).
InputEvent Hierarchy
InputEvent
├── InputEventKey ← keyboard
├── InputEventMouseButton ← mouse clicks
├── InputEventMouseMotion ← mouse movement
├── InputEventJoypadButton ← gamepad buttons
├── InputEventJoypadMotion ← gamepad sticks/triggers
├── InputEventScreenTouch ← touchscreen tap
├── InputEventScreenDrag ← touchscreen drag
├── InputEventAction ← synthetic action events
├── InputEventMIDI ← MIDI devices
└── InputEventGesture ← pinch, pan gestures
├── InputEventMagnifyGesture
└── InputEventPanGesture---
2. Input Map Setup
Define actions in **Project > Project Settings > Input Map** instead of checking raw keycodes. This decouples game logic from specific keys and enables rebinding.
Default Project Actions
Godot ships with `ui_*` actions: `ui_accept`, `ui_cancel`, `ui_left`, `ui_right`, `ui_up`, `ui_down`, etc. These are used by UI controls for keyboard navigation. You can use them for gameplay but creating custom actions is preferred to avoid conflicts.
Adding Actions in Code
Actions can be created at runtime with `InputMap.add_action()` + `InputMap.action_add_event()` — typically in an autoload `_ready()`, guarded by `InputMap.has_action()`. Define actions in the editor Input Map; only add them in code for dynamically generated bindings or mod support.
> See [references/action-rebinding.md](references/action-rebinding.md) for the GDScript and C# snippet.
Recommended Action Names
Use descriptive, game-specific names instead of key names:
| Good | Bad | Why | |---------------------|------------------|--------------------------------------| | `move_left` | `press_a` | Decoupled from physical key | | `attack` | `left_click` | Works for mouse and gamepad | | `interact` | `press_e` | Rebindable without changing logic | | `sprint` | `hold_shift` | Input-agnostic | | `pause` | `press_escape` | Can map to gamepad Start button too |
---
3. Reading Input — Events vs Polling
Event-Driven (Discrete Actions)
Use `_unhandled_input()` for one-shot actions: jump, attack, interact, pause.
GDScript
func _unhandled_input(event: InputEvent) -> void:
if event.is_action_pressed("jump"):
_jump()
get_viewport().set_input_as_handled() # prevent further propagation
if event.is_action_pressed("interact"):
_interact()
if event.is_action_pressed("pause"):
get_tree().paused = not get_tree().paused
get_viewport().set_input_as_handled()C#
public override void _UnhandledInput(InputEvent @event)
{
if (@event.IsActionPressed("jump"))
{
Jump();
GetViewport().SetInputAsHandled();
}
if (@event.IsActionPressed("interact"))
Interact();
if (@event.IsActionPressed("pause"))
{
GetTree().Paused = !GetTree().Paused;
GetViewport().SetInputAsHandled();
}
}Polling (Continuous Input)
Use `Input` singleton in `_physics_process()` for held buttons and analog axes.
GDScript
func _physics_process(delta: float) -> void:
# Movement vector from 4 directional actions
var direction := Input.get_vector("move_left", "move_right", "move_up", "move_down")
velocity = direction * speed
# Check if a button is held
if Input.is_action_pressed("sprint"):
velocity *= 1.5
move_and_slide()C#
public override void _PhysicsProcess(double delta)
{
Vector2 direction = Input.GetVector("move_left", "move_right", "move_up", "move_down");
Velocity = direction * Speed;
if (Input.IsActionPressed("sprint"))
Velocity *= 1.5f;
MoveAndSlide();
}Key Input Methods
| Method | Returns | Use For | |-----------------------------------|---------|--------------------------------------| | `Input.is_action_pressed()` | `bool` | Held buttons (sprint, crouch, fire) | | `Input.is_action_just_pressed()` | `bool` | One-shot triggers (jump, interact) | | `Input.is_action_just_re
Agentic skills framework for Godot 4.x game development. Gives AI coding agents domain-specific expertise for GDScript and C# projects.
Other skills on godot-prompter.
- /authoring-godot-prompter-skills
Use when writing or editing a SKILL.md or an agent definition in this repo — required frontmatter, section ordering, and the GDScript-then-C# example convention.
Open skill - /releasing-godot-prompter
Use when cutting a GodotPrompter release or bumping its version — the version-bump sequence, tag-triggered workflow, and the marketplace manifests that must follow.
Open skill - /2d-essentials
Use when working with 2D-specific systems — TileMaps, parallax scrolling, 2D lights and shadows, canvas layers, particles 2D, custom drawing, and 2D meshes in Godot 4.3+
Open skill - /3d-essentials
Use when working with 3D-specific systems — materials, lighting, shadows, environment, global illumination, fog, LOD, occlusion culling, and decals in Godot 4.3+
Open skill - /ability-system
Use when building character abilities — Resource-based abilities with cost/cooldown/cast, buffs/debuffs, stat modifiers, gameplay tags, and HUD binding
Open skill - /addon-development
Use when creating Godot editor plugins — EditorPlugin, @tool scripts, custom inspectors, and dock panels
Open skill

