如何在RigidBody移动中实现Dash:避免无限增速且保留空中控制
解决方案
核心思路是区分基础移动(WASD)和特殊动作(Dash)的速度贡献:只限制WASD带来的基础速度不超过上限,允许Dash等动作突破上限,同时保留空中的方向操控性。
步骤1:添加状态与变量
在脚本中新增变量用于标记冲刺状态、区分速度限制:
private bool isDashing; [SerializeField] private float dashSpeedLimit; // 冲刺时的临时速度上限,可按需调整
步骤2:修改Dash函数
更新冲刺逻辑,标记冲刺状态,可选择保留原有动量(无需强制重置速度):
private void Dash() { isDashing = true; // 可选:不需要完全重置速度的话,移除下面两行 rb.velocity = new Vector3(0, 0, 0); rb.angularVelocity = new Vector3(0, 0, 0); rb.AddForce(orientation.forward * hDashForce, ForceMode.Impulse); rb.AddForce(transform.up * vDashForce, ForceMode.Impulse); // 冲刺结束后恢复正常速度限制,这里设为0.3秒 StartCoroutine(EndDashAfterDelay(0.3f)); } private IEnumerator EndDashAfterDelay(float delay) { yield return new WaitForSeconds(delay); isDashing = false; }
步骤3:重构MovePlayer函数
修改基础移动逻辑,仅在当前移动方向的速度未达上限时加力,避免空中无限加速:
private void MovePlayer() { if (moveDirection.magnitude < 0.1f) return; // 无输入时跳过计算 moveDirection = moveDirection.normalized; Vector3 flatVel = new Vector3(rb.velocity.x, 0f, rb.velocity.z); // 计算当前平向速度在移动方向上的投影分量 float currentSpeedInMoveDir = Vector3.Dot(flatVel, moveDirection); // 只有移动方向的速度未达上限时,才添加基础移动力 if (currentSpeedInMoveDir < maxspeed) { float forceMultiplier = grounded ? 1f : airMultiplier; float forceToAdd = 10f * movespeed * forceMultiplier; rb.AddForce(moveDirection * forceToAdd, ForceMode.Force); } }
步骤4:调整SpeedControl函数
根据冲刺状态动态切换速度限制,同时保留空中方向调整空间:
private void SpeedControl() { Vector3 flatVel = new Vector3(rb.velocity.x, 0f, rb.velocity.z); float currentSpeedLimit = isDashing ? dashSpeedLimit : maxspeed; // 仅当平向速度超过当前限制时,才进行速度裁剪 if (flatVel.magnitude > currentSpeedLimit) { Vector3 limitedVel = flatVel.normalized * currentSpeedLimit; rb.velocity = new Vector3(limitedVel.x, rb.velocity.y, limitedVel.z); } }
逻辑说明
- 基础移动限制:通过计算速度在输入方向的投影,确保玩家无法在空中靠持续按方向键无限加速;但改变方向时,新方向的速度投影可能未达上限,因此仍能调整空中姿态,保留操控性。
- 冲刺突破上限:通过
isDashing状态切换速度阈值,冲刺时使用更高的上限,让冲刺动作能突破基础速度限制,结束后自动恢复。 - 流畅性优化:可移除Dash中的速度重置代码,让冲刺与当前移动动量叠加,体验更自然。
内容的提问来源于stack exchange,提问作者ErraticSignal
相关产品推荐
相关产品推荐

