Unity中如何为带Rigidbody的对象限制三个轴的旋转角度范围?
给带Rigidbody的物体添加旋转角度限制
因为你用的是Rigidbody组件,直接修改transform.rotation会破坏物理模拟的连贯性,所以得在物理更新周期(FixedUpdate)里做旋转修正,同时限制对应轴的角速度,确保物体不会超出指定角度范围。
实现思路
- 先定义每个轴允许的旋转角度区间(可在Inspector面板可视化调整)
- 在
Update里正常处理鼠标/触摸的旋转输入,通过AddTorque施加扭矩 - 在
FixedUpdate中检查当前旋转角度,若超出限制则修正到区间边界,并清零对应轴的角速度,避免继续旋转
修改后的完整代码
using UnityEngine; public class RotateWithLimit : MonoBehaviour { public Rigidbody rb; public float strength = 2f; // 鼠标旋转灵敏度,可在Inspector调整 // 定义各轴的旋转范围(单位:度),示例为X轴±30°、Y轴±45°、Z轴锁定0° public Vector3 minRotation = new Vector3(-30, -45, 0); public Vector3 maxRotation = new Vector3(30, 45, 0); private float rotX; private float rotY; void Update() { if (Input.GetMouseButton(0) || Input.touchCount > 0) { // 优先处理触摸输入,触摸的deltaPosition数值偏大,做灵敏度缩放 if (Input.touchCount > 0) { Touch touch = Input.touches[0]; rotX = touch.deltaPosition.x * strength * 0.1f; rotY = touch.deltaPosition.y * strength * 0.1f; } // 没有触摸时用鼠标输入 else { rotX = Input.GetAxis("Mouse X") * strength; rotY = Input.GetAxis("Mouse Y") * strength; } rb.AddTorque(rotY, -rotX, 0); } } void FixedUpdate() { // 将Unity默认0-360°的欧拉角转换为-180°到180°的范围,方便区间判断 Vector3 currentEuler = new Vector3( Mathf.DeltaAngle(0, transform.eulerAngles.x), Mathf.DeltaAngle(0, transform.eulerAngles.y), Mathf.DeltaAngle(0, transform.eulerAngles.z) ); // 修正X轴旋转 if (currentEuler.x < minRotation.x || currentEuler.x > maxRotation.x) { float clampedX = Mathf.Clamp(currentEuler.x, minRotation.x, maxRotation.x); rb.MoveRotation(Quaternion.Euler(clampedX, transform.eulerAngles.y, transform.eulerAngles.z)); rb.angularVelocity = new Vector3(0, rb.angularVelocity.y, rb.angularVelocity.z); } // 修正Y轴旋转 if (currentEuler.y < minRotation.y || currentEuler.y > maxRotation.y) { float clampedY = Mathf.Clamp(currentEuler.y, minRotation.y, maxRotation.y); rb.MoveRotation(Quaternion.Euler(transform.eulerAngles.x, clampedY, transform.eulerAngles.z)); rb.angularVelocity = new Vector3(rb.angularVelocity.x, 0, rb.angularVelocity.z); } // 修正Z轴旋转 if (currentEuler.z < minRotation.z || currentEuler.z > maxRotation.z) { float clampedZ = Mathf.Clamp(currentEuler.z, minRotation.z, maxRotation.z); rb.MoveRotation(Quaternion.Euler(transform.eulerAngles.x, transform.eulerAngles.y, clampedZ)); rb.angularVelocity = new Vector3(rb.angularVelocity.x, rb.angularVelocity.y, 0); } } }
关键细节说明
- 用
Mathf.DeltaAngle转换欧拉角范围,解决0°/360°交界处的区间判断问题 - 用
rb.MoveRotation修正旋转,而非直接修改transform.rotation,保证物理状态的一致性 - 修正后清零对应轴的角速度,避免物体因残留角速度继续突破限制
- 触摸输入做了灵敏度缩放,防止触摸滑动时旋转过快
内容的提问来源于stack exchange,提问作者Yidi
相关产品推荐
相关产品推荐

