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

Godot 3.5.1双击移动键切换奔跑功能失效问题求助

解决Godot第三人称控制器双击移动键触发奔跑无效的问题

你的脚本里双击移动键的逻辑完全没生效,核心原因是你把双击判断绑定到了SHIFT(run_key)的按下事件上,根本没监听移动方向键的双击操作,而且双击状态的逻辑和SHIFT奔跑的逻辑混在了一起,导致完全触发不了移动键的双击。

问题点拆解

  1. 原脚本里的is_double_tapping逻辑只在run_key(SHIFT)按下时更新,完全没处理移动键的输入
  2. 没有记录用户按下的是哪个移动键,无法判断是否是同一方向的连续双击
  3. 双击状态和SHIFT奔跑的逻辑耦合,导致逻辑混乱

修正后的完整脚本

extends KinematicBody

export var walk_speed = 5.0  # 行走速度
export var run_speed = 10.0  # SHIFT奔跑速度
export var sprint_speed = 20.0 # 双击移动键冲刺速度
export var gravity = 9.8  # 重力值
export var jump_power = 5.0  # 跳跃力度
export var run_key = "run"  # 奔跑按键(默认SHIFT)
export var weight = 1
export var double_tap_threshold = 0.3  # 双击时间阈值(可调整)

var velocity = Vector3.ZERO  # 角色速度向量
var is_running = false  # SHIFT奔跑状态
var is_sprinting = false # 双击冲刺状态
var last_move_action = "" # 记录上次按下的移动动作
var last_tap_time = 0.0 # 记录上次按键时间戳
var jumping = false # 跳跃状态

func _physics_process(delta):
    # 获取相机朝向和输入方向
    var move_dir = Vector3.ZERO
    var cam_transform = get_node("Camroot/Camera").global_transform
    var forward = -cam_transform.basis.z
    var right = cam_transform.basis.x
    move_dir = Input.get_action_strength("move_forward") * forward 
              - Input.get_action_strength("move_back") * forward 
              + Input.get_action_strength("move_right") * right 
              - Input.get_action_strength("move_left") * right
    move_dir = move_dir.normalized()

    # 处理双击移动键逻辑
    check_double_tap()

    # 确定当前目标速度
    var target_speed = walk_speed
    if is_running:
        target_speed = run_speed
    if is_sprinting:
        target_speed = sprint_speed
    velocity.x = move_dir.x * target_speed
    velocity.z = move_dir.z * target_speed

    # 应用重力
    if not is_on_floor() or abs(get_floor_normal().dot(Vector3.UP) - 1) > 0.001:
        velocity.y -= gravity * weight * delta

    # 处理跳跃
    if is_on_floor():
        if Input.is_action_just_pressed("jump"):
            jumping = true
    if jumping:
        velocity.y = jump_power
        jumping = false

    # 处理SHIFT奔跑逻辑
    if Input.is_action_just_pressed(run_key):
        is_running = true
    elif Input.is_action_just_released(run_key):
        is_running = false
        # 松开SHIFT时如果不在冲刺状态,重置速度到行走
        if not is_sprinting:
            target_speed = walk_speed

    # 移动角色
    velocity = move_and_slide(velocity, Vector3.UP)

func check_double_tap():
    # 监听四个移动方向键的按下事件
    var current_move_action = ""
    if Input.is_action_just_pressed("move_forward"):
        current_move_action = "move_forward"
    elif Input.is_action_just_pressed("move_back"):
        current_move_action = "move_back"
    elif Input.is_action_just_pressed("move_right"):
        current_move_action = "move_right"
    elif Input.is_action_just_pressed("move_left"):
        current_move_action = "move_left"

    if current_move_action != "":
        var current_time = OS.get_ticks_msec() / 1000.0 # 获取当前时间(秒)
        # 判断是否是同一方向的双击
        if current_move_action == last_move_action and (current_time - last_tap_time) < double_tap_threshold:
            is_sprinting = true
            # 重置计时器,保持冲刺状态直到松开方向键或超时
            last_tap_time = current_time
        else:
            # 第一次按下,记录动作和时间
            last_move_action = current_move_action
            last_tap_time = current_time
            is_sprinting = false
    else:
        # 没有移动键按下时,重置状态
        is_sprinting = false
        last_move_action = ""

关键改动说明

  • 新增check_double_tap()函数专门处理双击逻辑,独立于SHIFT奔跑逻辑
  • 用last_move_action记录上次按下的移动方向,确保是同一方向的双击才触发冲刺
  • 用OS.get_ticks_msec()获取精确时间戳,避免依赖帧时间的误差
  • 双击触发后保持冲刺状态,直到松开移动键或再次操作
  • 分离了SHIFT奔跑和双击冲刺的状态,避免逻辑冲突

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.25 12:07:43