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

Unity2D新输入系统下冲刺无法为玩家添加速度的问题求助

2D平台游戏冲刺功能失效问题排查与解决

我正在使用Unity及新输入系统开发一款2D平台游戏,尝试实现类似《空洞骑士》/《蔚蓝》的冲刺功能:冲刺需根据玩家朝向水平推进角色,且仅能在跳跃时触发。但测试时冲刺功能无效:跳跃并冲刺时,角色仅以跑步速度水平移动,协程内的其他功能(如TrailRenderer)均正常运行,仿佛冲刺未添加任何速度。

以下是我的代码:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.InputSystem;

public class PlayerMovement : MonoBehaviour
{

    //drag and drop the component to the script in the inspector
    public Rigidbody2D rb;

    public Transform groundCheck;
    public LayerMask groundLayer;
    public Animator myAnimator;
    public ParticleSystem dust;
    
    //this will make the public float accessible in the inspector
    private float horizontal;
    public float speed = 8f;
    public float jumpingPower = 16f;
    private bool isFacingRight = true;
    
    //coyote time
    public float coyoteTime = 0.1f;
    private float coyoteTimeCounter;
    
    //Dash goes here
    bool canDash = true;
    bool isDashing;
    [SerializeField] float dashForce = 30f;
    [SerializeField] float dashTime = 0.2f; 
    [SerializeField] float dashCooldown = 1f;
    [SerializeField] TrailRenderer dashTrail;
    //Dash Ends here
    
    void Start()
    {
        canDash = true;
    
    }
    
    
    void Update()
    {
        if (IsGrounded())
        {
            coyoteTimeCounter = coyoteTime;
        }
        else
        {
            coyoteTimeCounter -= Time.deltaTime;
        }
    
        if (!isFacingRight && horizontal > 0f)
        {
            Flip();
        }
        else if (isFacingRight && horizontal < 0f)
        {
            Flip();
        }
    
        if (isDashing)
        {
            return;
        }
    
        //Falling();
    
    }
    
    private void FixedUpdate()
    {
        rb.velocity = new Vector2(horizontal * speed, rb.velocity.y);
    
        if (isDashing)
        {
            return;
        }
    }
    
    
    public void Move(InputAction.CallbackContext context)
    {
        horizontal = context.ReadValue<Vector2>().x;
    
        if (Mathf.Abs(horizontal) > 0f)
        {
            myAnimator.SetBool("isRunning", true);
        }
        else
        {
            myAnimator.SetBool("isRunning", false);
        }
    }
    
    
    public void Jump(InputAction.CallbackContext context)
    {
        
        if (context.performed && coyoteTimeCounter > 0f)
        {
            CreateDust();
            rb.velocity = new Vector2(rb.velocity.x, jumpingPower);
        }
    
        if (context.canceled && rb.velocity.y > 0f)
        {
            rb.velocity = new Vector2(rb.velocity.x, rb.velocity.y * 0.5f);
    
            coyoteTimeCounter = 0f;
        }
    }
    
    
    private bool IsGrounded()
    {
        return Physics2D.OverlapCircle(groundCheck.position, 0.5f, groundLayer);
    }
    
    private void Flip()
    {
        CreateDust();
        isFacingRight = !isFacingRight;
        Vector3 localScale = transform.localScale;
        localScale.x *= -1f;
        transform.localScale = localScale;
    }
    
    
    public void Dash(InputAction.CallbackContext context)
    {
        if (context.performed && canDash && !IsGrounded())
        {
            StartCoroutine(Dash());
        }
    }
    
    private IEnumerator Dash()
    {
        canDash = false;
        isDashing = true;
        float originalGravity = rb.gravityScale;
        rb.gravityScale = 0f;
        rb.velocity = new Vector2(transform.localScale.x * dashForce, 0f); //issue? feels like the player isnt speeding up   
        dashTrail.emitting = true;
        yield return new WaitForSeconds(dashTime);
        dashTrail.emitting = false;
        rb.gravityScale = originalGravity;
        isDashing = false;
        yield return new WaitForSeconds (dashCooldown);
        canDash = true;
    }
    
    void CreateDust()
    {
        dust.Play();
    }

}

我猜测问题出在协程中的这一行,但不确定该如何修改:

rb.velocity = new Vector2(transform.localScale.x * dashForce, 0f);

问题根源分析

你猜的没错,核心问题确实和速度设置有关,但真正的原因是FixedUpdate的执行顺序把冲刺速度覆盖了。

看你的FixedUpdate逻辑:

private void FixedUpdate()
{
    rb.velocity = new Vector2(horizontal * speed, rb.velocity.y);

    if (isDashing)
    {
        return;
    }
}

这里你先把角色水平速度重置为跑步速度,再判断是否在冲刺并退出。也就是说,哪怕开启了冲刺,FixedUpdate还是会先覆盖掉你设置的冲刺速度,再退出——等于白设置了。

修复方案

  1. 调整FixedUpdate的判断顺序
    先检查是否在冲刺,如果是直接return,避免覆盖冲刺速度:
private void FixedUpdate()
{
    if (isDashing)
    {
        return;
    }
    rb.velocity = new Vector2(horizontal * speed, rb.velocity.y);
}
  1. 优化冲刺方向判断
    用isFacingRight变量替代transform.localScale.x更可靠(避免后期不小心修改了缩放比例导致方向错误):
// 替换Dash协程里的速度设置行
rb.velocity = new Vector2(isFacingRight ? dashForce : -dashForce, 0f);
  1. 可选:优化冲刺手感
    如果想让冲刺时不打断跳跃的上升/下落(更接近《空洞骑士》的手感),可以保留原y轴速度:
rb.velocity = new Vector2(isFacingRight ? dashForce : -dashForce, rb.velocity.y);

额外调试建议

测试时可以在Dash协程里加一句日志,确认冲刺速度是否正确设置:

Debug.Log("当前冲刺速度: " + rb.velocity);

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 04:17:56