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

Unity平台跳跃项目二段跳、冲刺失效及角色偶发冻结问题

Unity平台跳跃功能故障修复

故障根因

你的代码有4个直接触发异常的逻辑错误:

  • 方法嵌套定义错误:doubleJump()和Dash()两个功能方法被写在了Update()方法内部,C#不支持在方法内嵌套定义可执行的类方法,且你从未主动调用这两个方法,二段跳、冲刺逻辑从始至终没有运行过,这是按键无响应的核心原因。
  • 输入检测逻辑错误:所有单次触发的操作(跳跃、冲刺、充能)全部使用Input.GetKey()(按住时每帧触发),会导致功能触发时机完全失控;同时充能逻辑写在OnCollisionEnter2D中,仅在碰撞接触的单帧执行,玩家几乎不可能刚好在碰到能量球的那一帧精准按下充能键,充能成功率接近0。
  • 移动冻结的直接诱因:冲刺逻辑没有做方向兜底,当玩家静止不按方向键时按冲刺,会直接把刚体X轴速度设为0;同时每帧强制覆盖刚体速度的写法没有保留物理反馈,碰撞后速度被重置为0时如果没有新的方向输入,就会直接卡住,必须再次按方向键重新给速度才能恢复。
  • 变量混用错误:跳跃的上抛力直接复用了水平移动的speed变量,没有单独配置跳跃力、冲刺速度参数,数值稍有不对就会出现跳不起来、冲刺速度异常的问题。

修复方案

  • 将嵌套在Update内的两个功能方法移到类层级,和jump()方法平级,在Update生命周期中正确调用
  • 所有单次触发的输入替换为Input.GetKeyDown(),避免每帧重复触发
  • 能量球改为触发器检测:勾选能量球碰撞体的Is Trigger选项,用OnTriggerStay2D检测玩家处于能量球范围内的按键输入,不需要卡单帧碰撞时机
  • 冲刺逻辑增加方向兜底:无方向输入时默认朝角色当前面朝方向冲刺,避免速度直接归0卡住
  • 拆分速度变量,单独配置水平移动速度、跳跃力、冲刺速度,方便调参

修复后完整代码

public class playerMovement : MonoBehaviour
{
    [SerializeField] private float moveSpeed = 8f;
    [SerializeField] private float jumpForce = 16f;
    [SerializeField] private float dashSpeed = 25f;
    [SerializeField] int dashEnergy = 1;
    [SerializeField] int doubleJumpEnergy = 1;
    private Rigidbody2D body;
    private int jumpCount;
    // 记录角色当前面朝方向,1为右,-1为左
    private int faceDir = -1;

    private void Awake()
    {
        body = GetComponent<Rigidbody2D>();
    }

    private void Update()
    {
        // 水平移动输入
        float horizontalInput = Input.GetAxis("Horizontal");
        
        // 基础跳跃
        if(Input.GetKeyDown(KeyCode.Space) && jumpCount == 0)
        {
            Jump();
            jumpCount += 1;
        }

        // 每帧更新刚体速度
        body.velocity = new Vector2(horizontalInput * moveSpeed, body.velocity.y);

        // 角色朝向翻转
        if (horizontalInput > 0.01f)
        {
            transform.localScale = new Vector3(-5, 5, 5);
            faceDir = -1;
        }
        if (horizontalInput < -0.01f)
        {
            transform.localScale = new Vector3(5,5,5);
            faceDir = 1;
        }

        // 调用功能方法
        DoubleJump();
        Dash();
    }

    private void DoubleJump()
    {
        if(Input.GetKeyDown(KeyCode.Space) && jumpCount == 1 && doubleJumpEnergy == 1)
        {
            Jump();
            doubleJumpEnergy -= 1;
            jumpCount += 1;
        }
    }

    private void Dash()
    {
        if(Input.GetKeyDown(KeyCode.LeftShift) && dashEnergy == 1)
        {
            // 方向兜底:无输入时按面朝方向冲刺
            float dashDir = faceDir;
            float horizontalInput = Input.GetAxis("Horizontal");
            if (Mathf.Abs(horizontalInput) > 0.01f)
            {
                dashDir = horizontalInput > 0 ? -1 : 1;
            }
            body.velocity = new Vector2(dashDir * dashSpeed, body.velocity.y);
            dashEnergy -=1;
        }
    }

    public void Jump()
    {
        body.velocity = new Vector2(body.velocity.x, jumpForce);
    }

    private void OnCollisionEnter2D(Collision2D collision)
    {
        if (collision.gameObject.tag == "Ground")
        {
            jumpCount = 0;
        }
    }

    private void OnTriggerStay2D(Collider2D other)
    {
        if(other.tag == "EnergyBubble")
        {
            if(Input.GetKeyDown(KeyCode.V))
            {
                dashEnergy += 1;
                // 充能后销毁能量球,避免重复充能
                Destroy(other.gameObject);
            }
            if(Input.GetKeyDown(KeyCode.C))
            {
                doubleJumpEnergy += 1;
                Destroy(other.gameObject);
            }
        }
    }
}

额外配置提示

  • 给能量球的碰撞体勾选Is Trigger,否则触发器检测不会生效
  • 玩家对象的Rigidbody2D建议勾选Freeze Rotation的Z轴选项,避免角色移动时翻倒
  • 如果需要给冲刺加冷却、无敌帧,可以自行添加计时器协程扩展,当前代码为基础可用版本

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 20:24:09