Unity3D中如何仅修改物体Transform的Pitch旋转且不转欧拉角?
无需转换欧拉角修改GameObject的Pitch旋转
当然可以,直接通过四元数和向量运算就能实现,完全避开欧拉角的歧义问题。下面提供两种可靠的实现方式:
方法一:基于方向向量构造目标旋转
核心思路是保留原旋转的水平朝向(Yaw)和倾斜角度(Roll),仅调整Pitch对应的垂直朝向:
using UnityEngine; public class PitchAdjuster : MonoBehaviour { public GameObject targetObject; public float targetPitchDegrees = 30f; // 目标Pitch角度(单位:度) public void SetPitchWithoutEuler() { Quaternion originalRotation = targetObject.transform.rotation; // 提取原旋转的向前、向上向量 Vector3 originalForward = originalRotation * Vector3.forward; Vector3 originalUp = originalRotation * Vector3.up; // 获取仅包含Yaw的水平向前向量(消除Pitch影响) Vector3 horizontalForward = new Vector3(originalForward.x, 0f, originalForward.z).normalized; // 处理边界情况:当原向前向量完全垂直时,默认使用正前方 if (horizontalForward.sqrMagnitude < 0.001f) { horizontalForward = Vector3.forward; } // 创建目标Pitch对应的旋转四元数 Quaternion pitchRotation = Quaternion.AngleAxis(targetPitchDegrees, Vector3.right); // 计算应用目标Pitch后的新向前向量 Vector3 targetForward = pitchRotation * horizontalForward; // 用新向前向量和原向上向量构造最终旋转(保留Yaw和Roll) Quaternion newRotation = Quaternion.LookRotation(targetForward, originalUp); targetObject.transform.rotation = newRotation; } }
方法二:分解原旋转并替换Pitch分量
通过向量运算提取原旋转的Yaw+Roll部分,再与目标Pitch旋转组合:
using UnityEngine; public class PitchAdjuster : MonoBehaviour { public GameObject targetObject; public float targetPitchDegrees = 30f; public void SetPitchWithoutEuler() { Quaternion originalRotation = targetObject.transform.rotation; // 通过向前向量计算原Pitch角度(无欧拉角歧义,范围-90°~90°) Vector3 originalForward = originalRotation * Vector3.forward; float originalPitchRadians = Mathf.Asin(originalForward.y); Quaternion originalPitchRot = Quaternion.AngleAxis(originalPitchRadians * Mathf.Rad2Deg, Vector3.right); // 提取原旋转中的Yaw+Roll部分 Quaternion yawRollRotation = originalRotation * Quaternion.Inverse(originalPitchRot); // 创建目标Pitch的旋转四元数 Quaternion targetPitchRot = Quaternion.AngleAxis(targetPitchDegrees, Vector3.right); // 组合得到最终旋转:先应用Yaw+Roll,再应用目标Pitch Quaternion newRotation = yawRollRotation * targetPitchRot; targetObject.transform.rotation = newRotation; } }
关键说明
- 两种方法都完全避开了
eulerAngles转换的歧义问题,直接通过四元数和向量运算实现需求 - 方法一更适合处理极端边界情况(比如物体完全朝上/朝下),方法二更贴近"分解-替换"的直观逻辑
- 注意Unity中四元数乘法顺序:
A * B表示先应用B旋转,再应用A旋转
内容的提问来源于stack exchange,提问作者Anonymous
相关产品推荐
相关产品推荐

