godot-input-handling by thedivergentai/gd-agentic-skills
npx skills add https://github.com/thedivergentai/gd-agentic-skills --skill godot-input-handling通过适当的缓冲和辅助功能支持来处理键盘、鼠标、游戏手柄和触摸输入。
用于实现响应式跳跃、冲刺和连招的逐帧完美输入缓冲系统。
支持冲突检测、持久化和多设备的动态输入重绑定。
用于模拟摇杆的径向死区管理,可在保持自然跟随感的同时消除漂移。
处理触摸、拖拽和捏合缩放手势,以实现移动设备和触摸屏的兼容性。
过滤回显事件,以区分按住导航(UI)和一次性游戏操作。
适用于 FPS 和鼠标密集型系统的稳健鼠标捕获和灵敏度缩放逻辑。
广告位招租
在这里展示您的产品或服务
触达数万 AI 开发者,精准高效
软件层面支持用户定义的“按住”与“切换”辅助功能偏好。
根据最后活动的设备,实时在键盘和游戏手柄 UI 提示之间切换。
追踪一个动作的生命周期(“刚刚按下”、“按住”、“释放”),用于复杂的状态逻辑。
演示如何正确使用 _unhandled_input 来防止游戏逻辑泄漏到 UI 中。
强制要求 - 用于实现响应式控制:在实现跳跃/冲刺机制之前,请阅读 input_buffer.gd。
_process() 中轮询输入以处理游戏操作 — 使用 _physics_process() 或 _unhandled_input()。_process() 依赖于帧率,在低 FPS 时会导致输入丢失 [22]。KEY_W) — 始终使用 InputMap 动作。硬编码的按键会阻止重绑定,并破坏与非 QWERTY 布局的兼容性 [23]。Input.joy_connection_changed 来动态更新 UI 提示 [25]。_input() 处理游戏操作 — _input() 会触发所有事件(包括 UI)。使用 _unhandled_input(),这样点击菜单时就不会触发游戏逻辑 [26]。Input.is_action_pressed() 处理一次性触发 — 它在按键按住的每一帧都返回 true。对于跳跃、攻击和切换操作,请使用 _just_pressed 以避免逻辑重复触发。InputEvent.is_echo() — 回显事件(键盘重复)应该移动菜单,但很少应该触发“确认”或“返回”操作。ui_cancel,用户就会被困住。始终为鼠标捕获提供一个备用退出方式。设置: 项目设置 → 输入映射 → 添加动作
# 检查本帧是否按下了动作
if Input.is_action_just_pressed("jump"):
jump()
# 检查动作是否被按住
if Input.is_action_pressed("fire"):
shoot()
# 检查动作是否被释放
if Input.is_action_just_released("jump"):
release_jump()
# 获取轴(-1 到 1)
var direction := Input.get_axis("move_left", "move_right")
# 获取向量
var input_vector := Input.get_vector("left", "right", "up", "down")
func _input(event: InputEvent) -> void:
if event is InputEventKey:
if event.keycode == KEY_ESCAPE and event.pressed:
pause_game()
if event is InputEventMouseButton:
if event.button_index == MOUSE_BUTTON_LEFT and event.pressed:
click_position = event.position
# 检测控制器连接
func _ready() -> void:
Input.joy_connection_changed.connect(_on_joy_connection_changed)
func _on_joy_connection_changed(device: int, connected: bool) -> void:
if connected:
print("Controller ", device, " connected")
每周安装数
75
仓库
GitHub 星标数
59
首次出现
2026 年 2 月 10 日
安全审计
已安装于
opencode74
codex72
gemini-cli72
kimi-cli71
github-copilot71
amp71
Handle keyboard, mouse, gamepad, and touch input with proper buffering and accessibility support.
Frame-perfect input buffering system for responsive jumps, dashes, and combo chains.
Dynamic input rebinding with conflict detection, persistence, and multi-device support.
Radial deadzone management for analog sticks to eliminate drift while maintaining natural follow-through.
Handling touch, drags, and pinch-to-zoom gestures for mobile and touchscreen compatibility.
Filtering echo events to distinguish between hold-to-navigate (UI) and one-time gameplay actions.
Robust mouse capture and sensitivity scaling logic for FPS and mouse-intensive systems.
Software-side support for user-defined 'Hold' vs 'Toggle' accessibility preferences.
Real-time switching between Keyboard and Gamepad UI prompts based on the last active device.
Tracking the lifecycle of an action ('Just Pressed', 'Held', 'Released') for complex state logic.
Demonstrating the correct use of _unhandled_input to prevent gameplay logic from leaking into UI.
MANDATORY - For Responsive Controls : Read input_buffer.gd before implementing jump/dash mechanics.
_process() for gameplay actions — Use _physics_process() or _unhandled_input(). _process() is frame-rate dependent, causing dropped inputs at low FPS [22].KEY_W) — Always use InputMap actions. Hardcoded keys prevent rebinding and break compatibility with non-QWERTY layouts [23].Input.joy_connection_changed to update UI prompts dynamically [25]._input() for gameplay actions — fires for ALL events (including UI). Use so gameplay logic doesn't trigger while clicking menus [26].Setup: Project Settings → Input Map → Add action
# Check if action pressed this frame
if Input.is_action_just_pressed("jump"):
jump()
# Check if action held
if Input.is_action_pressed("fire"):
shoot()
# Check if action released
if Input.is_action_just_released("jump"):
release_jump()
# Get axis (-1 to 1)
var direction := Input.get_axis("move_left", "move_right")
# Get vector
var input_vector := Input.get_vector("left", "right", "up", "down")
func _input(event: InputEvent) -> void:
if event is InputEventKey:
if event.keycode == KEY_ESCAPE and event.pressed:
pause_game()
if event is InputEventMouseButton:
if event.button_index == MOUSE_BUTTON_LEFT and event.pressed:
click_position = event.position
# Detect controller connection
func _ready() -> void:
Input.joy_connection_changed.connect(_on_joy_connection_changed)
func _on_joy_connection_changed(device: int, connected: bool) -> void:
if connected:
print("Controller ", device, " connected")
Weekly Installs
75
Repository
GitHub Stars
59
First Seen
Feb 10, 2026
Security Audits
Gen Agent Trust HubPassSocketPassSnykPass
Installed on
opencode74
codex72
gemini-cli72
kimi-cli71
github-copilot71
amp71
agent-browser 浏览器自动化工具 - Vercel Labs 命令行网页操作与测试
163,300 周安装
_input()_unhandled_input()Input.is_action_pressed() for one-time triggers — It returns true every frame the key is held. Use _just_pressed for jumps, attacks, and toggles to avoid logic spam.InputEvent.is_echo() in UI navigation — Echo events (keyboard repeat) should move menus but rarely should they trigger "Confirm" or "Back" actions.ui_cancel, the user is trapped. Always provide a fallback escape for mouse capture.