godot-2d-movement
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseGodot 2D Movement (4.x)
Godot 2D 角色移动(4.x版本)
Build responsive 2D character controllers with and the argument-less
. Targets Godot 4.3+.
CharacterBody2Dmove_and_slide()使用和无参数的构建响应式2D角色控制器。适配**Godot 4.3+**版本。
CharacterBody2Dmove_and_slide()When to use
适用场景
- Use when scripting a 2D player/enemy that moves and collides: platformer (gravity + jump) or top-down (free 8-direction), slope walking, or wall/floor detection.
- Use when "does nothing", the character sinks through floors, or
move_and_slide()is always false.is_on_floor()
When not to use: dynamic rigid bodies, areas, raycasts, collision layers →
; tile-based levels → ; full platformer game template →
the genre skill; engine-agnostic feel tuning → .
godot-physicsgodot-tilemapplatformerphysics-tuning- 适用于编写可移动并发生碰撞的2D玩家/敌人控制器:平台类(重力+跳跃)或俯视角(自由8方向)角色、斜坡行走,以及墙体/地面检测。
- 适用于“无作用”、角色穿过地面下落,或
move_and_slide()始终返回false的情况。is_on_floor()
不适用场景: 动态刚体、区域、射线检测、碰撞层 → 参考;瓦片地图关卡 → 参考;完整平台游戏模板 → 参考类型技能;引擎无关的手感调校 → 参考。
godot-physicsgodot-tilemapplatformerphysics-tuningCore workflow
核心工作流程
- Use with a
CharacterBody2Dchild. It is script-driven: it does not fall or react to forces on its own.CollisionShape2D - Set the property, then call
velocity(no arguments in 4.x). The method readsmove_and_slide(), moves the body, slides along surfaces, and updatesvelocityto reflect what actually happened.velocity - Do it in —
_physics_process(delta)uses the physics step's delta internally, so do not multiplymove_and_slide()byvelocityyourself.delta - Platformer: add gravity to each tick, jump by setting
velocity.ynegative whenvelocity.y.is_on_floor() - Top-down: build a direction from input and scale by speed; set
so there is no "floor/wall" distinction.
motion_mode = MOTION_MODE_FLOATING - Read results with ,
is_on_floor(),is_on_wall(), andget_wall_normal()after the call.get_slide_collision(i)
- **使用**并添加
CharacterBody2D子节点。它由脚本驱动:自身不会下落或对力做出反应。CollisionShape2D - 设置属性,然后调用
velocity(4.x版本无需参数)。该方法会读取move_and_slide()、移动物体、沿表面滑动,并更新velocity以反映实际运动情况。velocity - 在中执行 ——
_physics_process(delta)内部已考虑物理步骤的delta,因此无需自行将move_and_slide()乘以delta。velocity - 平台类角色: 每帧向添加重力,当
velocity.y为true时,将is_on_floor()设为负值实现跳跃。velocity.y - 俯视角角色: 根据输入构建方向向量并按速度缩放;设置,这样就不会区分“地面/墙体”。
motion_mode = MOTION_MODE_FLOATING - 读取结果:调用后,使用
move_and_slide()、is_on_floor()、is_on_wall()和get_wall_normal()获取运动结果。get_slide_collision(i)
Patterns
实现模式
1. Platformer controller (gravity, jump, slopes)
1. 平台类控制器(重力、跳跃、斜坡)
gdscript
extends CharacterBody2D
@export var speed := 200.0
@export var jump_velocity := -400.0
@export var gravity := 1200.0 # pixels/sec^2 (tune to taste)
func _physics_process(delta: float) -> void:
# Apply gravity while airborne.
if not is_on_floor():
velocity.y += gravity * delta
# Jump only when grounded (Input action set in Project Settings > Input Map).
if Input.is_action_just_pressed("jump") and is_on_floor():
velocity.y = jump_velocity
# Horizontal input: -1, 0, or 1.
var dir := Input.get_axis("move_left", "move_right")
if dir != 0.0:
velocity.x = dir * speed
else:
velocity.x = move_toward(velocity.x, 0.0, speed) # decelerate to a stop
move_and_slide() # 4.x: no arguments; uses and updates `velocity`gdscript
extends CharacterBody2D
@export var speed := 200.0
@export var jump_velocity := -400.0
@export var gravity := 1200.0 # 像素/秒²(可根据手感调整)
func _physics_process(delta: float) -> void:
# 在空中时施加重力。
if not is_on_floor():
velocity.y += gravity * delta
# 仅在落地时跳跃(输入动作需在项目设置>输入映射中配置)。
if Input.is_action_just_pressed("jump") and is_on_floor():
velocity.y = jump_velocity
# 水平输入:-1、0或1。
var dir := Input.get_axis("move_left", "move_right")
if dir != 0.0:
velocity.x = dir * speed
else:
velocity.x = move_toward(velocity.x, 0.0, speed) # 减速至停止
move_and_slide() # 4.x版本:无需参数;会使用并更新`velocity`2. Top-down 8-direction movement
2. 俯视角8方向移动
gdscript
extends CharacterBody2D
@export var speed := 220.0
func _ready() -> void:
motion_mode = CharacterBody2D.MOTION_MODE_FLOATING # no floor/ceiling concept
func _physics_process(_delta: float) -> void:
# get_vector returns a normalized-ish Vector2 from four input actions.
var input := Input.get_vector("move_left", "move_right", "move_up", "move_down")
velocity = input * speed
move_and_slide()gdscript
extends CharacterBody2D
@export var speed := 220.0
func _ready() -> void:
motion_mode = CharacterBody2D.MOTION_MODE_FLOATING # 无地面/天花板概念
func _physics_process(_delta: float) -> void:
# get_vector根据四个输入动作返回一个近似归一化的Vector2。
var input := Input.get_vector("move_left", "move_right", "move_up", "move_down")
velocity = input * speed
move_and_slide()3. Reading slide collisions after moving
3. 移动后读取滑动碰撞
gdscript
func _physics_process(delta: float) -> void:
# ... set velocity ...
move_and_slide()
for i in get_slide_collision_count():
var c := get_slide_collision(i)
var other := c.get_collider()
if other and other.is_in_group("enemies"):
take_damage(1) # touched an enemy while movinggdscript
func _physics_process(delta: float) -> void:
# ... 设置velocity ...
move_and_slide()
for i in get_slide_collision_count():
var c := get_slide_collision(i)
var other := c.get_collider()
if other and other.is_in_group("enemies"):
take_damage(1) # 移动时触碰到敌人4. Coyote time (forgiving jump just after leaving a ledge)
4. 郊狼时间(离开边缘后短时间内仍可跳跃)
gdscript
@export var coyote_time := 0.1
var _coyote := 0.0
func _physics_process(delta: float) -> void:
if not is_on_floor():
velocity.y += gravity * delta
_coyote -= delta
else:
_coyote = coyote_time
if Input.is_action_just_pressed("jump") and _coyote > 0.0:
velocity.y = jump_velocity
_coyote = 0.0
# ... horizontal input + move_and_slide() ...gdscript
@export var coyote_time := 0.1
var _coyote := 0.0
func _physics_process(delta: float) -> void:
if not is_on_floor():
velocity.y += gravity * delta
_coyote -= delta
else:
_coyote = coyote_time
if Input.is_action_just_pressed("jump") and _coyote > 0.0:
velocity.y = jump_velocity
_coyote = 0.0
# ... 水平输入 + move_and_slide() ...Pitfalls
常见陷阱
- 3.x signature is gone. (returning the new velocity) was removed. In 4.x set the
move_and_slide(velocity)property and callvelocitywith no args.move_and_slide()will not parse.move_and_slide(velocity, Vector2.UP) - Multiplying velocity by delta. already accounts for the physics delta. Setting
move_and_slide()makes the body crawl.velocity = dir * speed * delta - Movement in instead of
_processcauses frame-rate-dependent, jittery motion. Always move in_physics_process._physics_process - always false when
is_on_floor()is wrong (defaultup_direction), there is noVector2.UP, or you never calledCollisionShape2Dthis frame.move_and_slide() - Sinking through floors usually means the collision shape is missing/zero-sized, the
floor body is on a layer this body's mask doesn't include, or you moved the body via
instead of velocity +
position +=.move_and_slide() - Slope slipping while idle: keep (default) and set a
floor_stop_on_slope = trueso the body sticks to downward slopes.floor_snap_length
- 3.x版本的调用方式已移除。 (返回新velocity)已被移除。在4.x版本中,需设置
move_and_slide(velocity)属性后调用无参数的velocity。move_and_slide()无法被解析。move_and_slide(velocity, Vector2.UP) - 将velocity乘以delta。 已考虑物理delta。设置
move_and_slide()会导致角色移动极慢。velocity = dir * speed * delta - 在中处理移动而非
_process会导致移动依赖帧率、出现抖动。务必在_physics_process中处理移动。_physics_process - 始终返回false:可能是
is_on_floor()设置错误(默认是up_direction)、缺少Vector2.UP,或是本帧未调用CollisionShape2D。move_and_slide() - 穿过地面下落:通常意味着碰撞形状缺失/尺寸为0、地面物体所在的图层未被当前物体的碰撞掩码包含,或是通过而非velocity +
position +=移动物体。move_and_slide() - ** idle时沿斜坡下滑:** 保持(默认值)并设置
floor_stop_on_slope = true,使角色能贴合向下的斜坡。floor_snap_length
References
参考资料
- For one-way platforms, moving platforms, jump buffering, variable jump height, and
(manual collision response), read
move_and_collide().references/controller-recipes.md
- 如需了解单向平台、移动平台、跳跃缓冲、可变跳跃高度以及(手动碰撞响应),请阅读
move_and_collide()。references/controller-recipes.md
Related skills
相关技能
- — collision layers/masks, areas, raycasts, rigid bodies.
godot-physics - — building the levels this character walks on.
godot-tilemap - — driving sprite/skeletal animation from movement state.
godot-animation - — follow camera, deadzone, and look-ahead that track this character.
camera-systems - /
platformer— full genre template and rebindable input.input-systems
- —— 碰撞层/掩码、区域、射线检测、刚体。
godot-physics - —— 构建角色行走的关卡。
godot-tilemap - —— 根据移动状态驱动精灵/骨骼动画。
godot-animation - —— 跟踪角色的跟随相机、死区和前瞻功能。
camera-systems - /
platformer—— 完整类型模板和可重新绑定的输入系统。input-systems