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

Unity中如何为带Rigidbody的对象限制三个轴的旋转角度范围?

给带Rigidbody的物体添加旋转角度限制

因为你用的是Rigidbody组件,直接修改transform.rotation会破坏物理模拟的连贯性,所以得在物理更新周期(FixedUpdate)里做旋转修正,同时限制对应轴的角速度,确保物体不会超出指定角度范围。

实现思路

  1. 先定义每个轴允许的旋转角度区间(可在Inspector面板可视化调整)
  2. 在Update里正常处理鼠标/触摸的旋转输入,通过AddTorque施加扭矩
  3. 在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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.17 12:05:35