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

Unity2D玩家Y轴恒为-7速度、下落动画异常问题排查

问题背景

编程初学者开发2D新项目,已完成跳跃、下落动画接入,设定规则为玩家Y轴速度小于0时自动激活下落动画。运行时出现异常:点击播放按钮后,玩家对象Y轴速度始终固定为-7,无法归零。
相关实现代码如下:

void OnMove()
{
    Vector2 vec = actions.Movement.Move.ReadValue<Vector2>();

    playerVelocity = new Vector2 (vec.x * speed, rb2d.velocity.y);
    rb2d.velocity = playerVelocity;
}

void OnJump()
    {
        isGrounded = Physics2D.OverlapCircle(groundCheck.position, checkRadius, whatIsGround);

        if(isGrounded)
        {
            animator.SetBool("isFalling", false);
        }

        if(isGrounded && actions.Movement.Jump.GetButtonDown())
        {
            isJumping = true;
            jumpTimeCounter = jumpTime;
            rb2d.velocity += new Vector2 (0f, jumpForce);        
        }

        if(actions.Movement.Jump.GetButton() && isJumping == true)
        {
            animator.ResetTrigger("hasJumped");
            animator.SetBool("isFalling", false);
            animator.SetTrigger("hasJumped");

            if (jumpTimeCounter > 0)
            {
                rb2d.velocity = new Vector2 (0f, jumpForce);
                jumpTimeCounter -= Time.deltaTime;
                animator.SetTrigger("hasJumped");
            }
            else
            {
                isJumping = false;
                animator.SetBool("isFalling", false);
                animator.ResetTrigger("hasJumped");
            }
        }

        if(rb2d.velocity.y < 0)
        {
            animator.SetBool("isFalling", true);
        }
    }

对应Inspector面板配置截图:
Inspector面板配置截图

问题原因

速度固定为-7是典型的对象未与地面产生物理碰撞、持续下落达到空气阻尼终端速度的表现,同时代码逻辑存在多处新手常见错误:

  • 配置类问题:
    • 玩家碰撞体勾选了Is Trigger,无法和地面产生实体碰撞,会直接穿透地形持续下落,直到线性阻尼把下落速度拉到稳定终端值(当前参数下刚好是-7)
    • 地面检测层掩码whatIsGround未勾选地面所在层,或groundCheck点位偏移过大、检测半径太小,始终判定玩家处于空中
    • 物理逻辑写在帧更新方法中,和Unity FixedUpdate物理更新节奏不同步,导致速度赋值异常
  • 代码逻辑问题:
    • 长按跳跃的逻辑中,强制把Rigidbody2D的X轴速度设为0,会导致跳跃过程中水平移动完全失效
    • 未处理跳跃按键松开的状态重置,isJumping标志位容易出现状态异常
    • 跳跃计时使用Time.deltaTime,帧率波动时跳跃时长不稳定
    • 跳跃力耗尽时强制把isFalling设为false,会导致下落动画触发延迟或失效
    • 落地后未钳制Y轴残留速度,容易出现动画状态切换错误
修复方案

第一步:排查修正配置

  • 选中玩家的Collider2D组件,取消勾选Is Trigger选项,保证碰撞体能和地面产生实体碰撞,不会穿模
  • 检查whatIsGround层掩码,确认所有地面/平台所在的层都已被勾选
  • 调整groundCheck对象的位置到玩家碰撞体的最下沿,把检测半径checkRadius设为0.1~0.2,保证站在地面时能稳定检测到地面碰撞体
  • 确认Rigidbody2D的Body Type为Dynamic,不要挂载Constant Force 2D这类会持续施加力的无关组件

第二步:修正代码逻辑

严格遵循Unity开发规则:输入读取放在Update中,所有修改Rigidbody2D速度的物理逻辑放在FixedUpdate中,修正后的参考代码如下:

// 缓存输入值的变量
private float moveInput;
private bool jumpPressed;
private bool jumpHeld;
private bool jumpReleased;

private void Update()
{
    // 仅在Update读取输入,不要直接修改刚体速度
    moveInput = actions.Movement.Move.ReadValue<Vector2>().x;
    jumpPressed = actions.Movement.Jump.WasPressedThisFrame();
    jumpHeld = actions.Movement.Jump.IsPressed();
    jumpReleased = actions.Movement.Jump.WasReleasedThisFrame();
}

private void FixedUpdate()
{
    // 所有物理逻辑统一在FixedUpdate执行
    isGrounded = Physics2D.OverlapCircle(groundCheck.position, checkRadius, whatIsGround);

    // 水平移动逻辑:仅修改X轴速度,保留Y轴原有物理速度
    rb2d.velocity = new Vector2(moveInput * speed, rb2d.velocity.y);

    if (isGrounded)
    {
        isJumping = false;
        animator.SetBool("isFalling", false);
        // 落地时钳制Y轴速度,清除残留下落速度
        if (rb2d.velocity.y < 0)
        {
            rb2d.velocity = new Vector2(rb2d.velocity.x, 0f);
        }

        // 触发起跳
        if (jumpPressed)
        {
            isJumping = true;
            jumpTimeCounter = jumpTime;
            rb2d.velocity = new Vector2(rb2d.velocity.x, jumpForce);
            animator.SetTrigger("hasJumped");
        }
    }

    // 松开跳跃键立刻中断跳跃,实现可变跳跃高度
    if (jumpReleased)
    {
        isJumping = false;
    }

    // 长按跳跃逻辑
    if (jumpHeld && isJumping)
    {
        animator.SetBool("isFalling", false);
        if (jumpTimeCounter > 0)
        {
            // 仅修改Y轴速度,保留X轴移动速度
            rb2d.velocity = new Vector2(rb2d.velocity.x, jumpForce);
            // 物理更新计时用fixedDeltaTime,保证帧率波动时跳跃时长稳定
            jumpTimeCounter -= Time.fixedDeltaTime;
        }
        else
        {
            isJumping = false;
        }
    }

    // 下落动画触发:不在地面且Y轴速度向下
    if (!isGrounded && rb2d.velocity.y < 0)
    {
        animator.SetBool("isFalling", true);
    }
}

修复后即可解决速度固定-7的问题,同时跳跃、移动、动画切换的手感会更稳定。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 06:12:22