You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Godot 4.0平台角色移动异常:添加摩擦力后无法停止

问题分析与修复方案

你的角色无法停止移动的核心原因是代码里的这一行:

velocity.x = previous_direction * speed

这行写在方向输入判断和摩擦力处理之后,会强制覆盖所有对velocity.x的修改——不管你有没有按方向键,不管摩擦力怎么计算,最终X轴速度都会被设为最大移动速度,所以角色永远停不下来。

具体修复步骤

1. 删除致命的覆盖代码

直接删掉velocity.x = previous_direction * speed这一行,这是导致问题的根源。

2. 调整摩擦力数值与逻辑

你的friction = 0.01太小了,乘以delta后每帧的减速量微乎其微,几乎看不到效果。建议把摩擦力设为和speed同量级的数值(比如200),而且move_toward的第三个参数是每帧要变化的绝对值,不需要额外乘以delta(_physics_process是固定帧率运行的)。

同时,你原本写的空中额外加速逻辑是错误的,会导致角色在空中反而加速,需要删掉这部分,只保留空中减速的逻辑。

3. 清理重复代码

代码里重复了两次跳跃判断,删掉其中一个即可。

4. 修正重力计算的括号问题

_ready函数里的重力计算缺少括号,会导致公式错误,需要补上。

修复后的完整代码

extends CharacterBody2D

@export var speed: float = 200.0

# Jumping physics
@export var jump_height: float
@export var jump_time_to_peak: float
@export var jump_time_to_descend: float

var jump_velocity: float
var jump_gravity: float
var fall_gravity: float

var previous_direction: int = 0

# 调整摩擦力为与speed同量级的数值
var friction: float = 200.0

var gravity: float = ProjectSettings.get_setting("physics/2d/default_gravity")

func _ready():
    jump_velocity = ((2.0 * jump_height) / jump_time_to_peak) * -1.0
    # 补上括号修正重力计算逻辑
    jump_gravity = ((-2.0 * jump_height) / (jump_time_to_peak * jump_time_to_peak)) * -1.0
    fall_gravity = ((-2.0 * jump_height) / (jump_time_to_descend * jump_time_to_descend)) * -1.0

func _physics_process(delta: float) -> void:
    velocity.y += _get_gravity() * delta
    
    var direction: float = Input.get_action_strength("move_right") - Input.get_action_strength("move_left")
    
    if direction != 0.0:
        previous_direction = 1 if direction > 0 else -1
        velocity.x = previous_direction * speed
    else:
        # 应用摩擦力减速,地面空中均生效(符合马里奥设计)
        velocity.x = move_toward(velocity.x, 0, friction * delta)
        # 避免浮点精度残留,速度接近0时直接归0
        if abs(velocity.x) < 1:
            velocity.x = 0
    
    # 保留单次跳跃判断
    if Input.is_action_just_pressed("jump") and is_on_floor():
        _jump()

    move_and_slide()

func _get_gravity() -> float:
    return jump_gravity if velocity.y < 0.0 else fall_gravity

func _jump() -> void:
    velocity.y = jump_velocity

额外说明

  • 修复后,松开方向键时角色会通过move_toward逐渐减速到0,地面和空中都有摩擦力,符合马里奥系列的操作逻辑。
  • 增加了速度归0的判断,避免浮点精度问题导致角色微小位移。

内容的提问来源于stack exchange,提问作者Jayden Dominguez

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.16 00:27:42