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

Unity2D新手求助:角色冲刺时异常浮空而非正常冲刺

Unity2D 跑步触发冲刺时角色浮空问题修复

问题根源

  1. 地面检测逻辑缺失:仅通过OnCollisionEnter2D设置isOnGround=true,未在离开地面时将其设为false,导致地面状态判断完全错误。
  2. 冲刺时垂直速度强制覆盖:当前代码直接用dashingDir的垂直分量覆盖刚体垂直速度,即使角色在地面上,未按垂直键时Y轴速度会被设为0,结合冲刺的水平速度,会让角色瞬间脱离地面,表现为浮空。
  3. 无效的速度恢复判断:if (dashingTime <= 0)永远不会触发,因为dashingTime是固定的序列化参数,运行中不会自动递减。

修复方案

  1. 完善地面检测,添加OnCollisionExit2D方法更新地面状态。
  2. 区分地面/空中冲刺逻辑:地面冲刺时仅保留水平方向的冲刺速度,垂直方向保持0(确保贴地);空中冲刺才允许使用垂直输入。
  3. 移除无效的速度恢复代码,确保冲刺结束后正确交回移动控制权。

修改后的代码

public class DashHollowKnight : MonoBehaviour
{
    [Header("Dashing")]
    [SerializeField]
    private float dashingVelocity = 14f;

    [SerializeField]
    private float dashingTime = 0.5f;

    private Vector2 dashingDir;
    private bool isDashing;
    private bool canDash = true;

    public float speed;
    public float moveInput;

    private bool isOnGround = true;
    public Animator animator;

    public Rigidbody2D playerRb;


    void Start()
    {
        
    }

    private void OnCollisionEnter2D(Collision2D col)
    {
        // 给地面对象添加Ground标签,避免碰撞其他物体时误判
        if (col.gameObject.CompareTag("Ground"))
        {
            isOnGround = true;
        }
    }

    private void OnCollisionExit2D(Collision2D col)
    {
        if (col.gameObject.CompareTag("Ground"))
        {
            isOnGround = false;
        }
    }

    void Update()
    {
        var dashInput = Input.GetButtonDown("Dash");

        if (dashInput && canDash)
        {
            isDashing = true;
            canDash = false;
            // 地面冲刺仅支持水平方向,忽略垂直输入
            if (isOnGround)
            {
                dashingDir = new Vector2(Input.GetAxisRaw("Horizontal"), 0);
                // 无水平输入时,默认朝角色当前朝向冲刺
                if (dashingDir.x == 0)
                {
                    dashingDir.x = transform.localScale.x;
                }
            }
            else
            {
                // 空中冲刺允许多方向输入
                dashingDir = new Vector2(Input.GetAxisRaw("Horizontal"), Input.GetAxisRaw("Vertical"));
                if (dashingDir == Vector2.zero)
                {
                    dashingDir = new Vector2(transform.localScale.x, 0);
                }
            }
            StartCoroutine(StopDashing());
        }

        animator.SetBool("IsDashing", isDashing);

        if (isDashing)
        {
            Vector2 dashVelocity = dashingDir.normalized * dashingVelocity;
            // 地面冲刺时保持垂直速度为0,确保角色贴地
            playerRb.velocity = isOnGround ? new Vector2(dashVelocity.x, 0) : dashVelocity;
            return;
        }

        // 此处保留你的角色移动逻辑(如果原本的移动代码写在其他脚本,需确保冲刺结束后逻辑正常接管)
        // moveInput = Input.GetAxisRaw("Horizontal");
        // playerRb.velocity = new Vector2(moveInput * speed, playerRb.velocity.y);
    }

    private IEnumerator StopDashing()
    {
        yield return new WaitForSeconds(dashingTime);
        isDashing = false;
        canDash = true;
        // 可选:冲刺结束后重置速度,避免残留冲刺惯性
        // playerRb.velocity = new Vector2(moveInput * speed, playerRb.velocity.y);
    }
}

额外说明

  • 务必给场景中的地面对象添加Ground标签,否则地面检测会失效。
  • 如果移动逻辑写在其他脚本中,需确保冲刺结束后,该脚本能重新控制刚体速度。
  • 地面冲刺强制忽略垂直输入,更贴合《空洞骑士》《蔚蓝》的设计逻辑——地面仅支持水平冲刺,空中才允许多方向冲刺。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 04:35:29