Input.is_action_pressed
2026/4/14大约 5 分钟
最后同步日期:2026-04-15 | Godot 官方原文 — Input.is_action_pressed
Input.is_action_pressed
定义
想象你正在开车——你的脚踩在油门上,只要你一直踩着,车就一直加速。is_action_pressed 就是用来检查"玩家是否正在按住某个按键"的。
它回答的是一个持续状态的问题:"此刻,这个按键是不是被按着?"就像你问朋友"你现在还在按门铃吗?"——只要你没松手,答案就是"是的"。
一句话总结
is_action_pressed = "你现在还在按着吗?"——只要按键没松开,每帧都返回 true。
和 is_action_just_pressed 的区别
is_action_pressed:按住不放期间,每一帧都返回true(适合持续移动、持续射击等)is_action_just_pressed:只有在按下那一瞬间返回true,之后即使继续按着也返回false(适合跳跃、开火等一次性操作)
函数签名
C#
public static bool IsActionPressed(StringName action, bool exactMatch = false)GDScript
is_action_pressed(action: StringName, exact_match: bool = false) -> bool参数说明
| 参数 | 类型 | 必需 | 说明 |
|---|---|---|---|
| action | StringName | 是 | 动作名称,在项目设置(Project Settings -> Input Map)中定义。比如 "move_left"、"jump" |
| exactMatch | bool | 否 | 是否精确匹配。默认 false,允许模糊匹配(例如同时绑定了键盘和手柄的同一个动作);设为 true 时只匹配完全相同的输入设备 |
返回值
bool — 如果指定的动作当前正在被按住,返回 true;否则返回 false。
代码示例
基础用法
最简单的用法——检测玩家是否正在按住"向右移动"动作:
C#
using Godot;
public partial class TestInput : Node
{
public override void _Process(double delta)
{
// 检查玩家是否正在按住 "ui_right"(默认绑定右箭头键和 D 键)
if (Input.IsActionPressed("ui_right"))
{
GD.Print("玩家正在按住 → 键");
}
// 如果没按住,则什么都不输出
// 运行结果: (按住右箭头时)每帧打印 "玩家正在按住 → 键"
// (松开后)不再打印
}
}GDScript
extends Node
func _process(delta: float) -> void:
# 检查玩家是否正在按住 "ui_right"(默认绑定右箭头键和 D 键)
if Input.is_action_pressed("ui_right"):
print("玩家正在按住 → 键")
# 如果没按住,则什么都不输出
# 运行结果: (按住右箭头时)每帧打印 "玩家正在按住 → 键"
# (松开后)不再打印实际场景
在一个 2D 平台游戏中,用 is_action_pressed 实现角色的左右移动——只要玩家按住方向键,角色就持续移动:
C#
using Godot;
public partial class Player : CharacterBody2D
{
[Export] public float ExMoveSpeed = 300f;
public override void _PhysicsProcess(double delta)
{
Vector2 velocity = Velocity;
// 检查左右移动:按住时持续移动,松开时停止
float direction = 0f;
if (Input.IsActionPressed("move_left"))
{
direction -= 1f;
}
if (Input.IsActionPressed("move_right"))
{
direction += 1f;
}
velocity.X = direction * ExMoveSpeed;
// 简单的重力效果
velocity.Y += 980f * (float)delta;
Velocity = velocity;
MoveAndSlide();
GD.Print("当前水平速度: " + Velocity.X);
// 运行结果: (按住右键时)当前水平速度: 300
// (按住左键时)当前水平速度: -300
// (都不按时)当前水平速度: 0
}
}GDScript
extends CharacterBody2D
@export var ex_move_speed: float = 300.0
func _physics_process(delta: float) -> void:
var velocity := velocity
# 检查左右移动:按住时持续移动,松开时停止
var direction := 0.0
if Input.is_action_pressed("move_left"):
direction -= 1.0
if Input.is_action_pressed("move_right"):
direction += 1.0
velocity.x = direction * ex_move_speed
# 简单的重力效果
velocity.y += 980.0 * delta
self.velocity = velocity
move_and_slide()
print("当前水平速度: " + str(self.velocity.x))
# 运行结果: (按住右键时)当前水平速度: 300.0
# (按住左键时)当前水平速度: -300.0
# (都不按时)当前水平速度: 0.0进阶用法
结合 is_action_pressed 实现一个完整的角色控制器,包括移动、冲刺和持续射击:
C#
using Godot;
public partial class AdvancedPlayer : CharacterBody2D
{
[Export] public float ExMoveSpeed = 300f;
[Export] public float ExSprintSpeed = 500f;
[Export] public float ExShootInterval = 0.15f;
private float _shootCooldown = 0f;
private bool _isSprinting = false;
public override void _PhysicsProcess(double delta)
{
// 1. 移动逻辑:检测四个方向
Vector2 inputDir = Vector2.Zero;
if (Input.IsActionPressed("move_left")) inputDir.X -= 1f;
if (Input.IsActionPressed("move_right")) inputDir.X += 1f;
if (Input.IsActionPressed("move_up")) inputDir.Y -= 1f;
if (Input.IsActionPressed("move_down")) inputDir.Y += 1f;
inputDir = inputDir.Normalized();
// 2. 冲刺检测:按住 Shift 时速度翻倍
_isSprinting = Input.IsActionPressed("sprint");
float currentSpeed = _isSprinting ? ExSprintSpeed : ExMoveSpeed;
Velocity = inputDir * currentSpeed;
MoveAndSlide();
// 3. 持续射击:按住射击键不放,每隔一段时间发射一颗子弹
_shootCooldown -= (float)delta;
if (Input.IsActionPressed("shoot") && _shootCooldown <= 0f)
{
Shoot();
_shootCooldown = ExShootInterval;
}
GD.Print($"移动方向={inputDir}, 冲刺={_isSprinting}, 速度={currentSpeed}");
// 运行结果: 移动方向=(1, 0), 冲刺=True, 速度=500
// 移动方向=(0, 0), 冲刺=False, 速度=300
}
private void Shoot()
{
GD.Print("发射子弹!");
// 运行结果: 发射子弹!(按住射击键时每 0.15 秒触发一次)
}
}GDScript
extends CharacterBody2D
@export var ex_move_speed: float = 300.0
@export var ex_sprint_speed: float = 500.0
@export var ex_shoot_interval: float = 0.15
var _shoot_cooldown: float = 0.0
var _is_sprinting: bool = false
func _physics_process(delta: float) -> void:
# 1. 移动逻辑:检测四个方向
var input_dir := Vector2.ZERO
if Input.is_action_pressed("move_left"): input_dir.x -= 1.0
if Input.is_action_pressed("move_right"): input_dir.x += 1.0
if Input.is_action_pressed("move_up"): input_dir.y -= 1.0
if Input.is_action_pressed("move_down"): input_dir.y += 1.0
input_dir = input_dir.normalized()
# 2. 冲刺检测:按住 Shift 时速度翻倍
_is_sprinting = Input.is_action_pressed("sprint")
var current_speed := ex_sprint_speed if _is_sprinting else ex_move_speed
velocity = input_dir * current_speed
move_and_slide()
# 3. 持续射击:按住射击键不放,每隔一段时间发射一颗子弹
_shoot_cooldown -= delta
if Input.is_action_pressed("shoot") and _shoot_cooldown <= 0.0:
_shoot()
_shoot_cooldown = ex_shoot_interval
print("移动方向=%s, 冲刺=%s, 速度=%s" % [input_dir, _is_sprinting, current_speed])
# 运行结果: 移动方向=(1, 0), 冲刺=True, 速度=500.0
# 移动方向=(0, 0), 冲刺=False, 速度=300.0
func _shoot() -> void:
print("发射子弹!")
# 运行结果: 发射子弹!(按住射击键时每 0.15 秒触发一次)注意事项
- 适用于持续状态检测:
is_action_pressed在按住按键期间每一帧都返回true,所以特别适合用来做持续移动、持续旋转、持续蓄力等操作。不要用它来触发一次性事件(比如跳跃、拾取物品),否则会导致事件在按住期间反复触发。 - 必须在 Input Map 中定义动作:调用此方法前,需要先在 Godot 编辑器的 项目设置 -> Input Map 中定义对应的动作名称(如
"move_left")。如果传入了未定义的动作名称,不会报错,但会始终返回false。 - 与
_PhysicsProcess配合更好:对于物理相关的移动(如MoveAndSlide),建议在_PhysicsProcess中使用此方法,而不是_Process,因为物理帧的间隔是固定的(默认 60fps),移动效果更稳定。 - C# 差异:C# 中方法名用 PascalCase(
Input.IsActionPressed),GDScript 中用 snake_case(Input.is_action_pressed)。
