Unity中如何限制玩家空中移动:落地前锁定起跳移动方向
空中水平移动锁定实现方案
核心实现逻辑
直接复用脚本中已经写好的isGrounded接地判断做状态分支,不需要额外搭建复杂状态机:
- 接地状态下:正常读取键盘/摇杆输入调整移动方向,触发跳跃的瞬间将当前的水平移动速度缓存到独立变量中
- 空中状态下:完全忽略新的方向输入,直接沿用起跳瞬间缓存的水平速度做位移,直到玩家重新接触地面
改动后的完整可运行代码
在原脚本基础上仅新增1个缓存水平速度的私有变量,拆分输入与位移的状态分支即可,不需要改动原有重力、跳跃、接地检测的核心逻辑:
public class PlayerMovement : MonoBehaviour { Vector3 velocity; // 缓存起跳瞬间锁定的水平移动速度 Vector3 lockedAirVelocity; public float speed = 12f; public float gravity = -9.81f; public CharacterController controller; public float jumpHeight = 3f; public Transform groundCheck; public float groundDistance = 0.4f; public LayerMask groundMask; bool isGrounded; // Update is called once per frame void Update() { isGrounded = Physics.CheckSphere(groundCheck.position, groundDistance, groundMask); if(isGrounded && velocity.y < 0) { velocity.y = -2f; } // 接地分支:正常响应用户输入 if (isGrounded) { float x = Input.GetAxis("Horizontal"); float z = Input.GetAxis("Vertical"); Vector3 move = transform.right * x + transform.forward * z; controller.Move(move * speed * Time.deltaTime); // 跳跃触发时,锁定当前的水平移动速度 if(Input.GetButtonDown("Jump")) { lockedAirVelocity = move * speed; velocity.y = Mathf.Sqrt(jumpHeight * -2f * gravity); } } // 空中分支:不读取新的方向输入,使用锁定速度位移 else { // 若需要空中速度衰减效果,可在此处添加:lockedAirVelocity *= 0.995f; controller.Move(lockedAirVelocity * Time.deltaTime); } // 保留原有垂直方向的重力计算逻辑 velocity.y += gravity * Time.deltaTime; controller.Move(velocity * Time.deltaTime); } }
注意事项
- 该改动不会影响原有地面操作手感,所有接地状态下的移动速度、转向响应和修改前完全一致
- 原有的地面检测参数(检测球体半径、层级遮罩、检测点位置)都不需要调整,保持Inspector面板的原有配置即可
- 如果需要做短距离空中微调的效果,可以适当降低空中锁定速度的衰减比例,不要完全锁死为恒定值
内容的提问来源于stack exchange,提问作者Gabe Clewis
相关产品推荐
相关产品推荐

