Unity3D中欧拉角的使用(一)
【写在前面】阅读本文需要对欧拉角的基本知识有一定的了解。如果有不清楚的地方,可以留言提问。
1. Unity 3d中与欧拉角有关的API
以下一共讲述了5个相关的API,前4个通过给transform组件的属性赋值实现旋转,最后1个直接使用transform组件的方法实现旋转。值得注意的是,前2个方法(包含local关键字)可以实现基于父节点坐标系的旋转。
1.transform.localRotation //transfrom组件属性
该属性表示了在父节点坐标系中的旋转情况。通常使用四元数来进行初始化。例如xxx.transform.localrotation=Quaternion.Euler(0.0f,0.0f,0.0f);
2.transform.localEulerAngles //transform组件属性
该属性也表示了在父节点坐标系中的旋转情况,只是直接通过欧拉角来初始化。例如
xxx.transform.localEulerAngles = new Vector3 (0.0f,0.0f,0.0f);
3.transform.rotation //transform组件属性
该属性表示了在全局坐标系下的旋转情况。通常使用四元数来赋值。例如xxx.transform.rotation=Quaternion.Euler(0.0f,0.0f,0.0f);
4.transfrom.eularAngles //transform组件属性
该属性也表示了在全局坐标系下的旋转情况,直接使用欧拉角来赋值。例如xxx.transform.eulerAngles = new Vector3(0.0f,0.0f,0.0f);
5.transform.Rotate(Vector3 eularAngles Space relativeTo) //transform组件方法
该方法同样是使得transform实例在参考坐标系中做旋转。同时该方法也可以实现绕某向量旋转(此处不做展开)。
2.欧拉角顺规
旋转的欧拉角按照先后旋转的顺序,共有12种顺规:非对称型欧拉角X-Y-Z X-Z-Y Y-X-Z Y-Z-X Z-X-Y Z-Y-X
,对称型欧拉角X-Y-X X-Z-X Y-X-Y Y-Z-Y Z-X-Z Z-Y-Z
。
分享一篇讲述旋转问题比较好的博客,可以参考。
3.关于API的使用测试
以下的测试都是基于以下图像进行的,在下面的图像中,从左至右分别是Cube0、Cube1、Cube2。且Cube0是根节点,Cube1是父节点,Cube2是子节点。
##3.1 Rotate方法使用
实例3.1.1:直接使用Rotate()控制立方体绕单一坐标轴旋转。
//调整三个立方体的位置,便于观察
cube0.transform.position = new Vector3(0.0f, 0.0f, 0.0f);
cube1.transform.position = new Vector3(0.0f, 0.0f, 2.0f);
cube2.transform.position = new Vector3(0.0f, 0.0f, 4.0f);
//控制根节点Cube0绕Z轴旋转45度
cube0.transform.Rotate(new Vector3(0.0f, 0.0f, 45.0f));
【结果分析】与初始图像对比,三个立方体都沿着蓝色的Z轴旋转了45°。说明Rotate()f方法确实起到了控制效果,且可以带动子节点一起转动。
实例3.1.2:直接使用Rotate()控制立方体绕两个坐标轴旋转。在前面代码的基础上修改为如下代码。cube0.transform.Rotate(0.0f,45.0f,45.0f)
.
【结果分析】发现此时立方体在Y轴和Z轴方向上都旋转了45°。下面增加两个实验,测试绕Y轴旋转和绕Z轴旋转的顺序。
【结果分析】该测试将原本Rotate(new Vector3(0.0f,45.0f,45.0f))
分解为两个部分执行。前一张图先绕Z轴旋转45°,然后再绕y轴旋转45°。后一张图的执行顺序相反。我们发现原本旋转的结果与第二种一样,说明Rotate(new Vector3(0.0f,45.0f,45.0f))
的旋转顺序是先绕Z轴旋转45°,然后绕Y旋转45°。
实例3.1.3
该实例中同时绕3个坐标轴都作一定角度的旋转。并且使用不同的参考坐标系。在之前的实例中均默认使用Space.Self为参考坐标系。下面的两个测试分别使用自身坐标系Space.Self和世界坐标系Space.World。
1)Space.Self
使用cube0.transform.Rotate(new Vector3(-30.0f, 45.0f, 45.0f), Space.Self);
控制,同时将其拆分为不同的顺序执行,例如
cube0.transform.Rotate(new Vector3(0.0f, 0.0f, 45.0f), Space.Self);
cube0.transform.Rotate(new Vector3(-30.0f, 0.0f, 0.0f), Space.Self);
cube0.transform.Rotate(new Vector3(0.0f, 45.0f, 0.0f), Space.Self); //Z-X-Y顺规
【结果分析】可以发现综合旋转与使用Y-X-Z
的结果是一致的,**这个结论是非常让人疑惑的。**换句话说,*中提到的Unity3d中顺规和此处是不相符的。
2)Space.World
使用cube0.transform.Rotate(new Vector3(-30.0f, 45.0f, 45.0f),Space.World);
控制,同时也将其拆分为不同的顺序执行,例如
cube0.transform.Rotate(new Vector3(0.0f, 0.0f, 45.0f), Space.World);
cube0.transform.Rotate(new Vector3(-30.0f, 0.0f, 0.0f), Space.World);
cube0.transform.Rotate(new Vector3(0.0f, 45.0f, 0.0f), Space.World); //Z-X-Y顺规
【结果分析】在使用世界坐标系作为旋转参照坐标系时,使用Z-Y-X
顺规分步执行的结果与综合执行的结果相同。该Z-Y-X顺规
是*中给的Unity 3d的顺规。
实例3.1.4
利用Rotate()控制子节点的旋转
【结果分析】Rotate()
方法针对父节点或者子节点的旋转都是一样的,都是基于全局坐标或者自身坐标系进行旋转。与父子节点没有任何联系。
利用transform属性来设置旋转的测试将在下一篇文章中进行讲解。
上一篇: python分布式爬虫搜索引擎实战-4-scrapy框架初体验
下一篇: AI坦克对战(实现人机)