在Unity中,旋转通常可以用一个三维向量(x,y,z)表示。实际上这是欧拉角。三个分量分别是绕x轴、y轴和z轴的旋转角度。
要对一个GameObject进行旋转,可以直接通过如下代码:
transform.Rotate(xAngle, yAngle, zAngle);
那么有如下疑问:
- 上述的x轴、y轴、z轴指的是哪组坐标轴?是世界坐标轴,还是局部坐标轴?
- 旋转的正方向如何?
- 旋转的顺序如何?
下面开始一一解答。
🟥 不同位置的旋转轴
1️⃣ 检视面板 Transform 的旋转数值
对于这一个情况,其显示的旋转轴既不是世界坐标轴,也不是本地坐标轴。(根本不是某些博客说的世界坐标那回事!否则解释不了下面的问题)
Editor中transform的旋转轴是父节点的坐标轴。
有小老弟就要问了啊:
橙哥,我这边怎么是这样转的呢,不是按照世界坐标系呀,
我的这个物体也没有根节点?
动手能力很强啊
这儿不得不又要提醒一个知识了:
父物体的旋转角度,会影响子物体的轴向。
我们对这个没有父物体的GameObject进行了X、Y旋转了45度,如果再对这个物体的Z进行旋转,
那么就相当于这个物体的父物体是一个(45,45,0)旋转角度的物体,这个物体是(0,0,0)旋转的物体,我们给这个物体旋转Z轴。
现在你再来看看,是不是绕着父物体Z轴转了?
2️⃣ Rotate函数,在Space.Self中旋转
该函数绕着该物体的局部坐标轴旋转。
为了让Space.Self、Space.World区别更明显,我们给这个物体创建一个父物体,父物体旋转角度为(45,45,45)。
比如:
void Update() { transform.Rotate(new Vector3(0, 0, 0.2f), Space.Self); }
它代表了每帧绕着该物体的Z轴,正向旋转0.2度。
3️⃣ Rotate函数,在Space.World中旋转
该函数让物体绕着世界坐标轴旋转。
比如:
void Update() { transform.Rotate(new Vector3(0, 0, 0.2f), Space.Self); }
它代表了每帧绕着世界坐标的Z轴,正向旋转0.2度。
🟧 旋转的正方向
Unity中局部坐标系和世界坐标系都是左手坐标系,
所以这里旋转的正方向可由左手法则判定。
🟨 静态欧拉角和动态欧拉角
前面说到的旋转轴的问题,在数学上有对应的概念。这就是所谓的静态欧拉角和动态欧拉角。
所谓静态欧拉角,就是其旋转轴使用的是静止不动的参考系。
动态欧拉角,使用的是物体本身作为参考系,因而参考系会随着刚体的旋转而旋转。
因此,使用Space.World旋转,是静态欧拉角;使用Space.Self旋转,是动态欧拉角。
🟩 旋转的顺序
即我们的欧拉角(xAngle, yAngle, zAngle)由三个分量组成,分别对应着绕x轴旋转,绕y轴旋转和绕z轴旋转,
那么是如何绕着这三个轴进行旋转的呢?
1️⃣ Unity的顺归
现在有一个问题了:
我们知道魔方,比如一个面的左上角,先左旋转90度,再上旋转90度,最后右旋转180度
跟先右旋转180度,再左旋转90度,最后上旋转90度,结果是不同的。
Unity同样了,不同的旋转顺序,物体最后的朝向是不同的。
那么一个(0,0,0)的物体,旋转(90,90,0)度,朝向是怎样的呢?Unity是先旋转哪个轴,再旋转哪个轴呢?
明确的指定出旋转顺序。这个顺序有一个专门的术语,称为顺规。
Unity的顺归是:Z-X-Y
即先旋转Z轴,再旋转X轴,最后旋转Y轴。
2️⃣ 动态欧拉角的旋转
静态欧拉角绕着世界坐标系以Z-X-Y的顺序进行旋转就好了,
那有的小老弟会问了:
橙哥啊,如果一个物体,起始状态为A,要绕自身旋转(20,45,60)度,旋转完Y轴时自身的轴方向就变了,这时为状态B
那再转X的20度时,是在B的基础上转,还是在起始状态A的基础上转呢?
这问题好啊,这问题一般人真答不上来
要被面试官问到绝对懵了
直接说答案:
后续所有旋转,全是以初始状态为参考,在初始状态A的基础上进行的。
下节我们再讲万向锁的问题~