初面网初面网

欧拉角与四元数

什么是欧拉角?

想象一下,你有一个玩具飞机。如果要让它转向,你可以:

  1. 左右转(偏航角 - Yaw):就像你用手扭动飞机的头部,让它向左或向右飞
  2. 上下俯仰(俯仰角 - Pitch):就像你让飞机抬头或低头
  3. 翻滚(翻滚角 - Roll):就像你让飞机侧着身子飞

这三个角度合起来就是欧拉角!在Unity中,这三个角度分别对应Transform组件中的Rotation的X、Y、Z值。

重要说明:在Unity中,欧拉角的旋转是围绕物体自身的坐标轴进行的,而不是世界坐标轴。而且旋转顺序是固定的:先绕Z轴旋转(翻滚),然后绕X轴旋转(俯仰),最后绕Y轴旋转(偏航)。

什么是四元数?

四元数听起来很复杂,但其实它就像是一个魔法工具,专门用来处理3D旋转的。

想象一下,你有一个指南针,它不仅能告诉你方向,还能记录你旋转的方式。四元数就像是这个超级指南针,它用四个数字来描述旋转,比欧拉角更准确。

为什么需要四元数?

欧拉角有一个大问题,叫做"万向锁"。让我们用玩具飞机来更清楚地理解:

想象一下,你的玩具飞机有三个自身的旋转轴

  1. Y轴(上下方向):控制飞机的左右转向(偏航)
  2. X轴(前后方向):控制飞机的俯仰(抬头低头)
  3. Z轴(左右方向):控制飞机的翻滚

在Unity中,欧拉角的旋转顺序是固定的:先绕Z轴旋转(翻滚),然后绕X轴旋转(俯仰),最后绕Y轴旋转(偏航)。

当你先绕X轴旋转90度(让飞机垂直向上飞),这时飞机自身的Y轴和Z轴就会重合在一起!就像两个轴粘在了一起,失去了一个自由度。这时候你再想左右转向(绕Y轴旋转),就会发现飞机不是左右转,而是开始翻滚了(绕Z轴旋转)。

这就是万向锁的根本原因:当欧拉角按照固定顺序旋转时,其中一个轴旋转90度会导致另外两个轴重合,失去一个旋转自由度。

而四元数使用了一种完全不同的方式来描述旋转,它不需要固定的旋转顺序,所以不会有万向锁的问题!

Unity中的代码示例

1. 使用欧拉角旋转物体

// 获取当前物体的欧拉角
Vector3 currentEuler = transform.eulerAngles;

// 设置新的欧拉角(让物体绕X轴旋转30度,Y轴旋转45度,Z轴旋转60度)
transform.eulerAngles = new Vector3(30f, 45f, 60f);

// 或者使用Rotate方法旋转
// 绕X轴旋转10度
transform.Rotate(10f, 0f, 0f);

// 绕Y轴旋转15度
transform.Rotate(0f, 15f, 0f);

// 绕Z轴旋转20度
transform.Rotate(0f, 0f, 20f);

2. 使用四元数旋转物体

// 获取当前物体的四元数
Quaternion currentQuat = transform.rotation;

// 使用四元数设置旋转(让物体绕X轴旋转30度)
Quaternion rotation = Quaternion.Euler(30f, 0f, 0f);
transform.rotation = rotation;

// 或者使用Quaternion.LookRotation让物体看向某个方向
Vector3 lookDirection = new Vector3(1f, 0f, 1f);
transform.rotation = Quaternion.LookRotation(lookDirection);

// 平滑旋转(比如让物体慢慢转向目标方向)
Vector3 targetDirection = new Vector3(0f, 0f, 1f);
Quaternion targetRotation = Quaternion.LookRotation(targetDirection);
// 使用Slerp方法进行平滑插值
transform.rotation = Quaternion.Slerp(transform.rotation, targetRotation, Time.deltaTime * 2f);

什么时候用欧拉角,什么时候用四元数?

  • 欧拉角:当你需要直观地设置旋转角度时,比如在Inspector面板中调整物体的朝向,或者在代码中设置一个明确的旋转角度。

  • 四元数:当你需要处理复杂的旋转,比如平滑旋转、避免万向锁问题,或者需要进行旋转的数学计算时。

小练习

  1. 创建一个立方体,使用欧拉角让它绕三个轴分别旋转不同的角度。
  2. 再创建一个球体,使用四元数让它平滑地转向不同的方向。

这样你就能感受到两者的不同啦!

更新于 2026/2/26