Unity3D鼠标拖拽相机旋转时如何设置垂直旋转角度限制
实现方案
原有代码直接调用Rotate累加旋转的方式无法稳定限制垂直角度,核心原因是Unity Transform的欧拉角存在万向节锁问题,跨角度阈值时会出现数值跳变,直接读取角度做钳制会出现逻辑错误。
正确做法是单独维护水平、垂直两个旋转角度值,每次拖拽时只更新角度增量,对垂直角度做范围钳制后,再统一计算相机的最终位置和朝向,避免累计误差。
修改后的完整代码
[SerializeField] private Camera _camera; [SerializeField] private Transform target; private Vector3 previousPosition; // 单独记录水平、垂直旋转角度,避免直接读取Transform欧拉角的跳变问题 private float yaw; // 水平旋转角,支持360度无限制旋转 private float pitch; // 垂直旋转角,限制在-45~45度区间 // 配置参数,和原有逻辑保持一致,可根据需求自行调整 private const float rotateSensitivity = 180f; private const float cameraDistance = 3f; private const float cameraHeightOffset = 0.3f; void Start() { // 初始化时对齐相机初始旋转角度,避免进入播放模式视角跳变 Vector3 currentEuler = _camera.transform.eulerAngles; yaw = currentEuler.y; // 将0~360度区间的欧拉角转换为-180~180度区间,方便初始角度钳制 pitch = currentEuler.x > 180 ? currentEuler.x - 360 : currentEuler.x; pitch = Mathf.Clamp(pitch, -45f, 45f); } void Update() { if (Input.GetMouseButtonDown(0)) { previousPosition = _camera.ScreenToViewportPoint(Input.mousePosition); } if (Input.GetMouseButton(0)) { Vector3 currentMousePos = _camera.ScreenToViewportPoint(Input.mousePosition); Vector3 direction = previousPosition - currentMousePos; // 更新旋转角度 yaw += -direction.x * rotateSensitivity; pitch += direction.y * rotateSensitivity; // 核心逻辑:钳制垂直旋转角度在-45~45度范围内 pitch = Mathf.Clamp(pitch, -45f, 45f); // 计算相机最终位置和朝向 _camera.transform.position = target.position; // 旋转顺序和原有逻辑保持一致:先俯仰、再绕世界坐标轴水平旋转 _camera.transform.rotation = Quaternion.AngleAxis(yaw, Vector3.up) * Quaternion.AngleAxis(pitch, Vector3.right); // 偏移到正确的观察位置 _camera.transform.Translate(new Vector3(0, cameraHeightOffset, -cameraDistance)); previousPosition = currentMousePos; } }
关键修改点
- 新增
yaw和pitch变量独立存储旋转角度,从根源避免直接操作Transform旋转带来的角度不可控问题 - 每次更新垂直角度后立刻做范围钳制,完全不会超出-45~45度的限制区间
- 水平旋转角度未加任何限制,可正常实现360度环绕目标旋转
- 初始化时自动对齐相机初始视角,不会出现进入播放模式视角跳变的问题
- 将旋转灵敏度、相机距离、高度偏移抽为常量,后续调整参数更方便
- 旋转顺序和原有逻辑完全一致,修改后不会出现操作手感变化
内容的提问来源于stack exchange,提问作者Zishan
相关产品推荐
相关产品推荐

