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

如何优化Unity 2D俯视角游戏冲刺代码 修复输入检测及结构问题

核心问题根源

  • 输入漏检是因为在FixedUpdate中读取瞬时输入事件:Input.GetKeyDown仅在按键按下的那一帧返回true,FixedUpdate默认50次/秒,而Update通常远高于这个帧率,很容易出现按键按下的帧没有执行FixedUpdate,直接漏掉输入。你写的shiftHolder缓存逻辑就是在尝试修复这个问题,但写法不够规范。
  • 全放Update无法移动是因为Rigidbody2D的速度赋值属于物理操作,必须放在FixedUpdate中执行,否则不同设备帧率差异会导致移动/冲刺表现完全不一致,你的原代码也没有写常规移动的逻辑,只定义了runSpeed、horizontal变量没有使用。

优化建议

  • 输入逻辑全部放在Update中执行,仅把计算好的方向、状态标记传递给FixedUpdate处理物理逻辑,两边职责拆分干净
  • 删掉冗余的dashDir方向判断逻辑,直接用输入的移动向量计算方向,支持4/8方向冲刺,不需要写多层if嵌套
  • 清理不必要的中间变量,把不需要暴露到Inspector的变量改为私有,用[SerializeField]标记需要在编辑器调整的参数
  • 冲刺状态下阻断常规移动输入,避免方向键干扰冲刺速度

重构后完整代码

using UnityEngine;

public class PlayerController : MonoBehaviour
{
    // 组件引用
    private Rigidbody2D rb;

    // 常规移动参数
    [Header("移动设置")]
    [SerializeField] private float runSpeed = 5f;
    private Vector2 moveInput;

    // 冲刺参数
    [Header("冲刺设置")]
    [SerializeField] private float dashSpeed = 15f;
    [SerializeField] private float dashDuration = 0.2f;
    [SerializeField] private float dashCooldown = 1f; // 不需要冲刺冷却可以直接删掉

    // 状态变量
    private bool isDashing;
    private float dashTimer;
    private float cooldownTimer;
    private bool dashTriggered;

    void Start()
    {
        rb = GetComponent<Rigidbody2D>();
    }

    void Update()
    {
        // 冷却计时
        if (cooldownTimer > 0) cooldownTimer -= Time.deltaTime;

        // 读取移动输入,默认支持WASD和方向键
        moveInput = new Vector2(Input.GetAxisRaw("Horizontal"), Input.GetAxisRaw("Vertical")).normalized;

        // 读取冲刺输入,满足条件才标记触发
        if (Input.GetKeyDown(KeyCode.LeftShift) && cooldownTimer <= 0 && !isDashing && moveInput != Vector2.zero)
        {
            dashTriggered = true;
        }
    }

    void FixedUpdate()
    {
        if (isDashing)
        {
            // 冲刺计时结束后退出冲刺状态
            dashTimer -= Time.fixedDeltaTime;
            if (dashTimer <= 0)
            {
                isDashing = false;
                cooldownTimer = dashCooldown; // 不需要冷却可以删掉这行
            }
            return; // 冲刺时跳过常规移动逻辑
        }

        // 处理冲刺触发
        if (dashTriggered)
        {
            isDashing = true;
            dashTimer = dashDuration;
            rb.velocity = moveInput * dashSpeed;
            dashTriggered = false;
            Debug.Log("bich Im dashin'");
            return;
        }

        // 常规移动逻辑
        rb.velocity = moveInput * runSpeed;
    }
}

额外说明

  • 代码直接用Unity原生输入轴,不需要自己写多层按键判断逻辑
  • 如果你只需要4方向冲刺,只需要在读取moveInput后,把x和y中绝对值更小的那个值清零即可
  • 职责拆分后不会再出现输入漏检问题,物理表现也不会因为帧率变化出现异常

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 09:36:04