Unity2D新手求助:角色冲刺时异常浮空而非正常冲刺
Unity2D 跑步触发冲刺时角色浮空问题修复
问题根源
- 地面检测逻辑缺失:仅通过
OnCollisionEnter2D设置isOnGround=true,未在离开地面时将其设为false,导致地面状态判断完全错误。 - 冲刺时垂直速度强制覆盖:当前代码直接用
dashingDir的垂直分量覆盖刚体垂直速度,即使角色在地面上,未按垂直键时Y轴速度会被设为0,结合冲刺的水平速度,会让角色瞬间脱离地面,表现为浮空。 - 无效的速度恢复判断:
if (dashingTime <= 0)永远不会触发,因为dashingTime是固定的序列化参数,运行中不会自动递减。
修复方案
- 完善地面检测,添加
OnCollisionExit2D方法更新地面状态。 - 区分地面/空中冲刺逻辑:地面冲刺时仅保留水平方向的冲刺速度,垂直方向保持0(确保贴地);空中冲刺才允许使用垂直输入。
- 移除无效的速度恢复代码,确保冲刺结束后正确交回移动控制权。
修改后的代码
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
相关产品推荐
相关产品推荐

