Godot 2D 角色移动控制
将以下提示词粘贴到你的 AI 对话框中:
请根据 https://skillhub.cn/install/skillhub.md,安装 @user_3c6cb52e/godot-2d-movement-oyrq。
技能介绍
它解决的是什么问题
在 Godot 4.x 里写 2D 角色,最常见的翻车方式是:move_and_slide(velocity) 直接编译不过,或者能跑但角色穿地、is_on_floor() 永远是 false。这个技能面向的是用脚本驱动的 CharacterBody2D 控制器,而不是刚体物理。典型场景包括平台跳跃(重力 + 起跳)、俯视角自由八向移动、斜坡行走,以及贴墙与贴地判定。
它同时覆盖一类很难自查的运行时问题:角色每帧下沉、斜坡上静止时打滑、跳跃手感偏硬。
核心机制与关键步骤
底层只有一条主线:
- 结构:
CharacterBody2D作为根节点,挂一个CollisionShape2D子节点。它是脚本驱动的,不会自己下落,也不会自动响应外力。 - 驱动:先给
velocity属性赋值,再调用move_and_slide()。4.x 中这个方法不接受参数,它会读取velocity、移动、沿表面滑动,并把velocity更新为实际发生的值。 - 时机:全部放在
_physics_process(delta)里。move_and_slide()内部已经用了物理步长的 delta,所以不要自己再把velocity乘一遍 delta。 - 平台跳跃:每帧给
velocity.y加重力;在is_on_floor()为真时把velocity.y设为负值完成起跳。 - 俯视角:从输入合成方向向量并缩放到速度,同时把
motion_mode设为MOTION_MODE_FLOATING,这样就没有「地板 / 墙壁」的区分。 - 读结果:调用之后再取
is_on_floor()、is_on_wall()、get_wall_normal()和get_slide_collision(i)。
技能里给的现成模式包括:平台跳跃控制器(重力、跳跃、斜坡)、俯视角八向移动、移动后读取滑动碰撞,以及 Coyote time(离开平台边缘后短暂仍可起跳的宽容跳跃)。
适用边界与常见坑
不适合的场景:动态刚体、Area、RayCast、碰撞层/掩码(归 godot-physics)、TileMap 关卡搭建(归 godot-tilemap)、完整平台跳跃模板(归 platformer genre skill)、与引擎无关的手感调参(归 physics-tuning)。
几个高频坑:
- 3.x 签名已删除。带参数的
move_and_slide(velocity, Vector2.UP)无法解析,必须改为设置属性 + 无参调用。 - 自己乘 delta 会让角色像在爬行,因为方法内部已经处理过步长。
- 在
_process里做移动会导致帧率相关的抖动,一律用_physics_process。 is_on_floor()恒为假通常意味着up_direction不对、没有CollisionShape2D,或者这一帧根本没调用move_and_slide()。- 穿地多半是碰撞形状缺失或尺寸为零、地板所在层不在本身体的 mask 里,或者你用
position +=手动挪了节点。 - 斜坡静止打滑:保留
floor_stop_on_slope = true(默认值),再设一个floor_snap_length,角色就能贴住下行斜坡。
想继续做单向平台、移动平台、跳跃缓冲、可变跳跃高度,或用 move_and_collide() 手写碰撞响应,看技能内的 references/controller-recipes.md。
使用场景
- 在 Godot 4.x 项目里做平台跳跃原型,需要重力、起跳和斜坡贴地
- 俯视角玩法要实现自由八向移动,并正确区分地板和墙壁
- 角色穿地或 is_on_floor() 恒为 false,需要排查 move_and_slide 用法
- 已有控制器想加 Coyote time 或跳跃缓冲,改善离台瞬间的起跳手感
适合人员
- 独立游戏开发者,在 Godot 4 里需要快速搭出可玩的 2D 角色控制器
- 从 Godot 3.x 迁移过来的开发者,旧的 move_and_slide 带参代码无法编译
- 做课程项目或参加 Game Jam 的学生团队里负责角色操控手感的成员
- 接手他人 Godot 项目的工程师,需要排查角色穿地与斜坡打滑问题