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

Godot 4.3角色滑行机制实现问题:如何让滑行持续2秒?

Godot 4.3 CharacterBody3D 滑行持续2秒实现问题修复

现有代码的核心问题

  1. 无滑行计时机制:CAN_SLIDE被设为true后不会自动重置,无法限制2秒的滑行时长
  2. 未实现CTRL()函数:滑行的核心逻辑缺失,调用后无任何实际效果
  3. 移动逻辑冲突:正常移动的速度赋值会覆盖滑行状态下的速度,导致滑行效果被抵消
  4. 状态管理混乱:SLIDING变量未在滑行开始/结束时正确更新,无法区分滑行与正常状态

修复后的完整代码

extends CharacterBody3D

var SPEED : float

const WALK_SPEED = 4.5
var SPRINT_SPEED = 6.0
const JUMP_VELOCITY = 4.0
@onready var Head: AnimationPlayer = $Head

var FALL_DISTANCE = 0
var SLIDE_SPEED = 8.0  # 设定基础滑行速度
var CAN_SLIDE = false
var SLIDING = false
var FALLING = false
var slide_duration = 2.0  # 滑行持续时间
var slide_timer = 0.0     # 滑行计时器

@onready var slidecheck: RayCast3D = $Slidecheck

func _physics_process(delta: float) -> void:
    # 处理落地时的滑行速度加成
    if FALLING and is_on_floor() and SLIDING:
        SLIDE_SPEED += FALL_DISTANCE / 10
    FALL_DISTANCE = - velocity.y 
    
    # 重力处理
    if not is_on_floor():
        velocity += get_gravity() * delta
        FALLING = true 
    else:
        FALLING = false

    # 跳跃处理
    if Input.is_action_just_pressed("ui_accept") and is_on_floor():
        velocity.y = JUMP_VELOCITY

    # 滑行状态更新
    if SLIDING:
        # 累加计时器,超过时长后结束滑行
        slide_timer += delta
        if slide_timer >= slide_duration:
            end_slide()
    else:
        # 非滑行状态下处理正常移动
        handle_normal_movement(delta)

    # 触发滑行的条件判断
    if Input.is_action_just_pressed("CTRL") and is_on_floor() and SPEED > 3 and not SLIDING:
        start_slide()

    # sprint状态切换
    if Input.is_action_pressed("shift"):
        SPEED = SPRINT_SPEED
        Head.speed_scale = 1.5
    else:
        SPEED = WALK_SPEED
        Head.speed_scale = 1

    move_and_slide()

# 开始滑行的逻辑
func start_slide():
    SLIDING = true
    CAN_SLIDE = false
    slide_timer = 0.0
    # 基于当前移动方向设置滑行速度
    var move_dir = Vector3(velocity.x, 0, velocity.z).normalized()
    velocity.x = move_dir.x * SLIDE_SPEED
    velocity.z = move_dir.z * SLIDE_SPEED
    # 播放滑行动画(如果有)
    # Head.play("Slide")

# 结束滑行的逻辑
func end_slide():
    SLIDING = false
    slide_timer = 0.0
    # 恢复正常移动动画
    # Head.play("Head bob")

# 正常移动处理逻辑
func handle_normal_movement(delta: float):
    var input_dir := Input.get_vector("ui_left", "ui_right", "ui_up", "ui_down")
    var direction := (transform.basis * Vector3(input_dir.x, 0, input_dir.y)).normalized()
    if direction:
        velocity.x = direction.x * SPEED
        velocity.z = direction.z * SPEED
        Head.play("Head bob")
    else:
        velocity.x = move_toward(velocity.x, 0, SPEED)
        velocity.z = move_toward(velocity.z, 0, SPEED)
        Head.stop()

关键修复点说明

  • 新增slide_timer和slide_duration变量,通过delta累加实现2秒的滑行时长控制
  • 将正常移动逻辑封装到handle_normal_movement函数,仅在非滑行状态执行,避免与滑行速度冲突
  • 实现start_slide和end_slide函数,统一管理滑行的开始与结束状态
  • 调整滑行触发条件,确保同一时间只能触发一次滑行(避免重复触发)
  • 基于当前移动方向设置滑行速度,让滑行更符合玩家操作逻辑

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.01 15:53:11