Godot 4 CharacterBody2D 角色移动:输入、碰撞与八方向控制实战

Godot 4 CharacterBody2D 角色移动:输入、碰撞与八方向控制实战

刚接触 Godot 4 时,很多人会直接修改 Sprite2D.position 来移动玩家。画面确实动了,但角色遇到墙体时仍会穿过去,因为精灵只负责显示,不负责物理运动。

这篇文章从一个最小的俯视角角色场景出发,使用 CharacterBody2DCollisionShape2DInput.get_vector(),完成方向输入、等速斜向移动以及滑动碰撞。最终代码可以直接作为 RPG、射击或探索类 2D 游戏的移动基础。

一、先分清三种物理主体

Godot 4 中常见的二维物理主体有三种:

  • CharacterBody2D:速度由玩家代码或 AI 决定,适合角色。
  • StaticBody2D:提供固定阻挡,适合墙壁、地面和不可移动障碍。
  • RigidBody2D:主要由重力、碰撞与外力推动,适合箱子等物理对象。

关键不在于对象看起来会不会动,而在于"谁决定它如何运动"。玩家角色需要稳定、可预测的输入响应,因此这里选择 CharacterBody2D

二、搭建玩家场景

新建一个二维场景,将根节点设为 CharacterBody2D,命名为 Player。添加两个子节点:

text 复制代码
Player (CharacterBody2D)
├── AnimatedSprite2D
└── CollisionShape2D

AnimatedSprite2D 负责画面,CollisionShape2D 负责物理轮廓。两者应当分离:头发、武器和披风等装饰像素通常不该参与阻挡,否则玩家会觉得"明明没碰到墙却被卡住"。

CollisionShape2DShape 属性中创建矩形、圆形或胶囊形状,优先覆盖角色的主体区域。俯视角角色没有明确的地面方向,可以把 CharacterBody2DMotion Mode 设为 Floating

三、配置输入动作

打开 Project → Project Settings → Input Map,建立四个动作:

动作名 推荐按键
move_left A、左方向键
move_right D、右方向键
move_up W、上方向键
move_down S、下方向键

代码只依赖动作名,不直接依赖某个键。以后接入手柄或允许玩家改键时,不必重写移动逻辑。

四、编写八方向移动代码

Player 创建并附加 player_controller.gd

gdscript 复制代码
extends CharacterBody2D

@export var speed: float = 240.0

func _physics_process(_delta: float) -> void:
    var input_direction := Input.get_vector(
        "move_left",
        "move_right",
        "move_up",
        "move_down"
    )

    velocity = input_direction * speed
    move_and_slide()

这段代码只有三个关键步骤:

  1. Input.get_vector() 把四个动作合成为一个 Vector2
  2. 方向向量乘以 speed,得到角色速度。
  3. move_and_slide() 提交当前物理帧的速度并处理滑动碰撞。

不要再额外写 position += velocity * deltaCharacterBody2D 的运动应交给 move_and_slide(),否则可能避开预期的碰撞处理。

五、为什么斜着走不会更快

如果分别判断四个按键,再把 X、Y 速度都设为 speed,角色斜向移动时的合速度会大于水平速度。Input.get_vector() 会把最终向量长度限制在 1 以内,因此右下方向大约是 (0.707, 0.707),乘以速度后仍保持统一的最大移动速度。

这也是它比手工堆叠四个 if 更适合八方向控制的原因。

六、添加可碰撞的障碍

在测试场景中添加 StaticBody2D,并给它添加:

text 复制代码
Wall (StaticBody2D)
├── Sprite2D
└── CollisionShape2D

运行后让玩家斜着撞向墙角。正确结果是:

  • 角色不会穿过墙体;
  • 仍有切向速度时,角色会沿墙滑动;
  • 松开输入后,角色立即停止。

如果角色直接穿墙,依次检查:

  1. 玩家和墙体是否都有可用的 CollisionShape2D
  2. Shape 是否为空;
  3. 玩家与墙体的 Collision Layer 和 Mask 是否互相匹配;
  4. 是否错误地手动修改了 position
  5. move_and_slide() 是否在 _physics_process() 中执行。

七、加入平滑加速与减速

即时停止适合强调精准操作的游戏。如果希望移动更柔和,可以让速度逐步接近目标值:

gdscript 复制代码
extends CharacterBody2D

@export var max_speed: float = 240.0
@export var acceleration: float = 1200.0
@export var deceleration: float = 1600.0

func _physics_process(delta: float) -> void:
    var input_direction := Input.get_vector(
        "move_left",
        "move_right",
        "move_up",
        "move_down"
    )

    var target_velocity := input_direction * max_speed
    var rate := acceleration if not input_direction.is_zero_approx() else deceleration

    velocity.x = move_toward(velocity.x, target_velocity.x, rate * delta)
    velocity.y = move_toward(velocity.y, target_velocity.y, rate * delta)
    move_and_slide()

move_toward() 按固定变化率逼近目标速度,delta 用来抵消帧率差异。加速度和减速度分开后,可以做出"起步柔和、松手迅速"的手感。

八、常见错误

错误一:用 Sprite2D 当角色根节点

它可以显示和移动,但不会自动获得角色碰撞运动能力。需要把 CharacterBody2D 作为物理主体。

错误二:碰撞轮廓完全包住装饰像素

过大的形状容易让角色在狭窄通道和墙角处被卡住。物理轮廓应服务于玩法手感,而不是逐像素描边。

错误三:一个物理帧多次调用 move_and_slide()

先计算完整速度,再调用一次即可。把不同方向拆成多次移动会让碰撞结果难以预测。

错误四:把 velocity 再乘一次 delta

velocity 的单位是每秒像素数,move_and_slide() 会按物理步处理。只有加速度的变化量需要乘 delta

九、知识主线与参考

本文的节点选型、碰撞轮廓、Floating 运动模式和物理移动方法,来自《大鹏 Godot 4 游戏开发入门》第 5 章中"配置可移动物理角色"与"编写物理角色移动代码"两节。文章把这些知识整理成一个可独立复现的俯视角控制器,没有把同题搜索结果当作技术事实。

十、完整验收清单

  • 单独按 W、A、S、D 时方向正确。
  • 同时按两个方向时速度没有变快。
  • 松开输入后按预期立即停止或平滑减速。
  • 碰到墙体不会穿透。
  • 斜撞墙体时可以沿墙滑动。
  • 调整窗口刷新率后,移动速度基本一致。

总结

完成这些检查后,一个可复用的 Godot 4 二维角色移动底座就建立好了。下一步可以把 velocity 交给 AnimatedSprite2D,让站立和移动动画随真实运动状态自动切换。

相关推荐
show4331 天前
2026小程序端AI智能优化技术实践:转文字后自动纠错+润色+分段算法分析
人工智能·算法·小程序
今天AI了吗1 天前
Agent & AI 名词大扫盲
数据库·人工智能·python·sql·rust
iaku1 天前
Prompt 不是玄学:写给前端的 Prompt 工程指南
前端·人工智能
武子康1 天前
从 Pi 学习设计自己的 Agent Harness:一条可验证的垂直生产线
人工智能·llm·agent
HAHAXX81 天前
从传统RPA到AI增强RPA:内网离线部署、元素自愈与Prompt工程落地实践
人工智能·prompt·rpa
两万五千个小时1 天前
DeepSeek Harness 上下文压缩:长对话管理
人工智能·程序员·架构
有脚就行1 天前
第24篇-Go-gRPC推理服务-高性能跨语言通信
开发语言·人工智能·后端·golang
hyunbar7771 天前
玩转LlamaIndex:流式输出与并发执行
人工智能
哈__1 天前
Windows部署Next AI Draw.io:用大模型生成并修改draw.io图表
人工智能·draw.io
2301_780356701 天前
【技术解码】全视通“物联数据中台”如何打通医养结合全链路?
大数据·人工智能·物联网