1、gameObject的旋转由transform组件统一管理,需要研究透彻它的几个旋转相关的API;
旋转是以物体整体(包括自身坐标系)为单位的,会改变物体位置、朝向,但不会改变物体中各部件的相对位置;
2、三要素:旋转轴、旋转方向、旋转角度
旋转轴=定点+轴向量(它是以“定点自身坐标系”来定义的)
沿着“旋转轴”的正方向,顺时针为负,逆时针为正;
3、当前物体世界坐标系:世界坐标系原点与当前物体原点重合,但坐标系方向固定不变
当前物体父亲坐标系:父亲坐标系原点与当前物体原点重合,但坐标系方向与父亲坐标系方向一致
4、Transform中与旋转有关的API:
1)RotateAround(axis, angle) //通过“自身原点+向量”确定旋转轴,进行旋转;等效于Rotate(axis, angle)
RotateAround (point, axis, angle) //通过“point点的世界坐标位置+世界坐标系中axis向量”确定旋转轴,
可实现物体绕另外一个物体旋转
2)Rotate(eulerAngles, relativeTo) //以“自身原点or当前物体世界坐标系原点+eulerAngles向量”
确定旋转轴,eulerAngls的模为旋转的大小;
当relativeTo留空或Space.Self时,用自身原点;
当relativeTo=Space.World时,用世界坐标系原点;
Rotate(axis, angle,relativeTo) //以“自身原点or当前物体世界坐标系原点+axis向量”确定旋转轴,
angle为旋转的大小;
Rotate(xAngle, yAngle, zAngle, relativeTo) //以“自身原点or当前物体世界坐标系原点 + 坐标系3条轴向量”
确定旋转轴,变量值为旋转的大小;
它其实是进行了3次欧拉旋转的复合旋转;
[TIPS:Rotate只能绕着物体自身中心位置旋转]
3)Transform.LookAt(Transform target, worldUp) //使物体自身坐标系的Z轴指向target(XY平面的旋转?)
4)transform.eulerAngles = vector3 //通过“当前物体世界坐标系原点+eulerAngles向量”确定旋转轴,
eulerAngls的模为旋转的大小;
从“自身坐标系”与“世界坐标系”重叠处开始,即Vector3.Zero;
transform.localEulerAngles = vector3 //“当前物体父亲坐标系原点+localEulerAngles向量”确定旋转轴,
localEulerAngles的模为旋转的大小;
从“自身坐标系”与“当前物体父亲坐标系”重叠处开始;
5)rotation, localRotation //通过四元数设置旋转(参考UnityEngine.Quaternion四元数类)
6) 分“增量型”和“最终值型”,前者每调用一次旋转一次,后者只需调用一次就行了
增量型:RotateAround(), Rotate()
最终值型:LookAt(), eulerAngles, localEulerAngles, rotation, localRotation
5、3种旋转:
1)矩阵旋转:矩阵旋转使用了一个4*4大小的矩阵来表示绕任意轴旋转的变换矩阵;
优点:旋转轴可以是任意向量;
缺点:旋转其实只需要知道一个向量+一个角度,共4个值的信息,但矩阵法使用了16个元素;
而且在做乘法操作时也会增加计算量,造成了空间和时间上的一些浪费;
2)欧拉旋转:按照一定的坐标轴顺序(例如先x、再y、最后z)、每个轴旋转一定角度来变换坐标或向量,
它实际上是一系列坐标轴旋转的组合。
优点:很容易理解,形象直观;
表示更方便,只需要3个值(分别对应x、y、z轴的旋转角度);
但按我的理解,它还是转换到了3个3*3的矩阵做变换,效率不如四元数;
缺点:这种方法是要按照一个固定的坐标轴的顺序旋转的,因此不同的顺序会造成不同的结果;
会造成万向节锁(Gimbal Lock)的现象;
由于万向节锁的存在,欧拉旋转无法实现球面平滑插值;
3)四元数旋转:优点:可以避免万向节锁现象;
只需要一个4维的四元数就可以执行绕任意过原点的向量的旋转,更高效;
可以提供平滑插值;
缺点:比欧拉旋转稍微复杂了一点点,因为多了一个维度;
理解更困难,不直观;
6、四元数
参考http://blog.csdn.net/candycat1992/article/details/41254799