Input.get_vector
2026/4/14大约 6 分钟
最后同步日期:2026-04-15 | Godot 官方原文 — Input.get_vector
Input.get_vector
定义
想象你在玩一个俯视角的游戏——你用一个摇杆控制角色移动。摇杆推向哪个方向,角色就朝哪个方向走。get_vector 就是帮你把四个方向键(上、下、左、右)"融合"成一个方向向量的工具。
你只需要告诉它"哪个键代表左、哪个键代表右、哪个键代表上、哪个键代表下",它就会自动帮你算出一个 Vector2(二维向量)。比如同时按住右和上,它会返回大约 (1, -1) 这样的值,再经过归一化处理就是 (0.707, -0.707)——刚好是右上 45 度方向。
一句话总结
get_vector = "给我四个方向键的动作名,我还你一个方向向量"——一步到位获取 2D 移动方向,不用自己判断组合键。
和手动组合 is_action_pressed 的区别
- 手动方式:需要自己写四个
if判断,还要手动归一化,代码又长又容易出错 get_vector:一个调用搞定,自动处理方向组合和归一化,返回值长度始终为 0 或 1
函数签名
C#
public static Vector2 GetVector(string negativeX, string positiveX, string negativeY, string positiveY)GDScript
Input.get_vector(negative_x: String, positive_x: String, negative_y: String, positive_y: String) -> Vector2参数说明
| 参数 | 类型 | 必需 | 说明 |
|---|---|---|---|
| negativeX / negative_x | string | 是 | 负 X 方向(通常是"向左")对应的动作名称,比如 "move_left" |
| positiveX / positive_x | string | 是 | 正 X 方向(通常是"向右")对应的动作名称,比如 "move_right" |
| negativeY / negative_y | string | 是 | 负 Y 方向(通常是"向上",因为 Godot 的 Y 轴向下为正)对应的动作名称,比如 "move_up" |
| positiveY / positive_y | string | 是 | 正 Y 方向(通常是"向下")对应的动作名称,比如 "move_down" |
返回值
Vector2 — 一个归一化后的二维向量,表示玩家当前的移动方向。
- 只按一个方向键时:返回长度为 1 的轴向向量,如
(1, 0)或(0, -1) - 同时按两个方向键时:返回长度为 1 的对角向量,如
(0.707, 0.707)(即斜向归一化后的值) - 没有按任何键时:返回
(0, 0)
代码示例
基础用法
最简单的用法——用四个动作名获取移动方向向量:
C#
using Godot;
public partial class TestInput : Node
{
public override void _Process(double delta)
{
// 传入四个方向的动作名,直接获取方向向量
Vector2 direction = Input.GetVector("move_left", "move_right", "move_up", "move_down");
GD.Print("当前方向: " + direction);
// 运行结果: (只按右键时)当前方向: (1, 0)
// (同时按右+上时)当前方向: (0.707107, -0.707107)
// (什么都不按时)当前方向: (0, 0)
}
}GDScript
extends Node
func _process(delta: float) -> void:
# 传入四个方向的动作名,直接获取方向向量
var direction := Input.get_vector("move_left", "move_right", "move_up", "move_down")
print("当前方向: " + str(direction))
# 运行结果: (只按右键时)当前方向: (1, 0)
# (同时按右+上时)当前方向: (0.707107, -0.707107)
# (什么都不按时)当前方向: (0, 0)实际场景
在一个 2D 俯视角游戏中,用 get_vector 实现角色的八方向自由移动——比手动写四个 if 简洁得多:
C#
using Godot;
public partial class TopDownPlayer : CharacterBody2D
{
[Export] public float ExMoveSpeed = 200f;
public override void _PhysicsProcess(double delta)
{
// 一行代码获取移动方向,自动处理对角线归一化
Vector2 direction = Input.GetVector("move_left", "move_right", "move_up", "move_down");
// direction 已经是归一化向量,直接乘以速度即可
Velocity = direction * ExMoveSpeed;
MoveAndSlide();
GD.Print("位置: " + GlobalPosition + ", 速度: " + Velocity);
// 运行结果: 位置: (150.3, 82.1), 速度: (200, 0) ← 只按右
// 位置: (150.3, 82.1), 速度: (141.4, -141.4) ← 按右+上(归一化后斜向)
// 位置: (150.3, 82.1), 速度: (0, 0) ← 没按
}
}GDScript
extends CharacterBody2D
@export var ex_move_speed: float = 200.0
func _physics_process(delta: float) -> void:
# 一行代码获取移动方向,自动处理对角线归一化
var direction := Input.get_vector("move_left", "move_right", "move_up", "move_down")
# direction 已经是归一化向量,直接乘以速度即可
velocity = direction * ex_move_speed
move_and_slide()
print("位置: %s, 速度: %s" % [global_position, velocity])
# 运行结果: 位置: (150.3, 82.1), 速度: (200.0, 0.0) ← 只按右
# 位置: (150.3, 82.1), 速度: (141.4, -141.4) ← 按右+上(归一化后斜向)
# 位置: (150.3, 82.1), 速度: (0.0, 0.0) ← 没按进阶用法
结合 get_vector 实现一个带动画朝向、加速减速效果的完整角色控制器:
C#
using Godot;
public partial class AdvancedPlayer : CharacterBody2D
{
[Export] public float ExMoveSpeed = 250f;
[Export] public float ExAcceleration = 1200f;
[Export] public float ExFriction = 800f;
private AnimatedSprite2D _animatedSprite;
private Vector2 _velocity = Vector2.Zero;
public override void _Ready()
{
_animatedSprite = GetNode<AnimatedSprite2D>("AnimatedSprite2D");
}
public override void _PhysicsProcess(double delta)
{
// 获取输入方向(已归一化)
Vector2 direction = Input.GetVector("move_left", "move_right", "move_up", "move_down");
if (direction != Vector2.Zero)
{
// 有输入时:向目标方向加速
_velocity = _velocity.MoveToward(direction * ExMoveSpeed, ExAcceleration * (float)delta);
// 更新动画朝向(根据水平方向翻转精灵)
_animatedSprite.FlipH = direction.X < 0;
_animatedSprite.Play("run");
}
else
{
// 无输入时:减速到停止
_velocity = _velocity.MoveToward(Vector2.Zero, ExFriction * (float)delta);
_animatedSprite.Play("idle");
}
Velocity = _velocity;
MoveAndSlide();
GD.Print($"方向={direction}, 速度={_velocity}, 动画={_animatedSprite.Animation}");
// 运行结果: 方向=(1, 0), 速度=(250, 0), 动画=run ← 全速向右
// 方向=(0, 0), 速度=(120.5, 0), 动画=idle ← 松开按键后减速中
// 方向=(0, 0), 速度=(0, 0), 动画=idle ← 完全停止
}
}GDScript
extends CharacterBody2D
@export var ex_move_speed: float = 250.0
@export var ex_acceleration: float = 1200.0
@export var ex_friction: float = 800.0
@onready var _animated_sprite: AnimatedSprite2D = $AnimatedSprite2D
var _velocity := Vector2.ZERO
func _physics_process(delta: float) -> void:
# 获取输入方向(已归一化)
var direction := Input.get_vector("move_left", "move_right", "move_up", "move_down")
if direction != Vector2.ZERO:
# 有输入时:向目标方向加速
_velocity = _velocity.move_toward(direction * ex_move_speed, ex_acceleration * delta)
# 更新动画朝向(根据水平方向翻转精灵)
_animated_sprite.flip_h = direction.x < 0
_animated_sprite.play("run")
else:
# 无输入时:减速到停止
_velocity = _velocity.move_toward(Vector2.ZERO, ex_friction * delta)
_animated_sprite.play("idle")
velocity = _velocity
move_and_slide()
print("方向=%s, 速度=%s, 动画=%s" % [direction, _velocity, _animated_sprite.animation])
# 运行结果: 方向=(1, 0), 速度=(250.0, 0.0), 动画=run ← 全速向右
# 方向=(0, 0), 速度=(120.5, 0.0), 动画=idle ← 松开按键后减速中
# 方向=(0, 0), 速度=(0, 0), 动画=idle ← 完全停止注意事项
- 自动归一化:
get_vector返回的向量已经经过归一化处理,长度始终为 0 或 1。你不需要再手动调用Normalized()。这意味着斜向移动和正交移动的速度是一样的,不会出现"斜向移动更快"的老问题。 - 必须在 Input Map 中定义动作:调用此方法前,需要先在 Godot 编辑器的 项目设置 -> Input Map 中定义对应的四个动作名称(如
"move_left"、"move_right"、"move_up"、"move_down")。如果某个动作未定义,该方向将被视为没有按下。 - Y 轴方向:Godot 的 2D 坐标系中,Y 轴向下为正。所以参数
negativeY(负 Y 方向)通常对应"向上"的动作名,positiveY(正 Y 方向)通常对应"向下"的动作名。如果你发现角色移动方向反了,检查一下这里有没有搞错。 - 与
GetAxis的关系:get_vector本质上是同时调用两次get_axis(一次取 X 轴、一次取 Y 轴),然后把结果组合成Vector2。如果你只需要单轴方向值,可以用get_axis更轻量。 - C# 差异:C# 中方法名用 PascalCase(
Input.GetVector),GDScript 中用 snake_case(Input.get_vector)。
