本文共 3546 字,大约阅读时间需要 11 分钟。
01:欧拉角
1.欧拉角Vector3(x,y,z)代表的是旋转物体(若是标准旋转那么是旋转坐标轴x,y,z,转换为旋转物体则旋转角度取反顺序不变),且是将物体从物体坐标系旋转到惯性坐标系(世界坐标系中为了渲染),故旋转顺序为 z, y, x也就是roll pitch yaw。
2.欧拉角有别名和万向锁问题,不要随便增长欧拉角的值,也不要单独改变欧拉角的一个旋转角度值,而是用一个Vector3全部一起改变。
3.欧拉角来自于Transform.eulerAngles, 渲染时候也会转换到Transform.rotation四元数然后到旋转矩阵来旋转物体。
4.欧拉角插值使用 float fAngles = Mathf.MoveTowardsAngle(oldAngles, target, m_rotSpeed * Time.deltaTime); m_transform.eulerAngles = new Vector3(0, fAngles, 0);
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组件方法
欧拉角,Unity中没有专门的API,所以这里我们用transform和rigidbody相关的API进行讨论。
02:四元数
内部由四个数字(在Unity中称为x,y,z和w)组成,然而这些数字不表示角度或轴,并且通常不需要直接访问它们。 Unity里面的Transform组件里的Rotation是四元数,但是他是以欧拉角(Vector3)的形式展现在我们面前,目的就是为了方便我们修改。因此,我们给Rotation直接赋值的时候,也只能用Quaternion赋值。意识到这点很重要。private Transform cubeTransform; void Awake() { cubeTransform = this.GetComponent(); } void Start() { //修改欧拉角的角度 cubeTransform.eulerAngles=new Vector3(45,45,45); //获取欧拉角 Debug.Log("欧拉角"+cubeTransform.eulerAngles); //获取四元数 Debug.Log("四元数"+cubeTransform.rotation); //四元数转换为欧拉角 Debug.Log("四元数转换为欧拉角"+cubeTransform.rotation.eulerAngles); Debug.Log("欧拉角转换为四元数" + Quaternion.Euler(cubeTransform.eulerAngles)); //通过修改四元数来改变角度 cubeTransform.rotation=Quaternion.Euler(new Vector3(40,40,40)); }
四元数的常用API
LookRotation声明形式:public static Quaternion LookRotation ( Vector3 forward, Vector3 upwards=Vector3.up )这个功能很实用,传入的两个参数分别代表前方盯着的方向以及自己的上方向。它可以让一个GameObject转动脑袋盯着另一个物体。如:
public Transform target; void Update() { Vector3 relativePos = target.position - transform.position; Quaternion rotation = Quaternion.LookRotation(relativePos); transform.rotation = rotation; }
二、Angle
声明形式:public static float Angle ( Quaternion a, Quaternion b )这个就比较简单了,它可以计算两个旋转之间的夹角。与Vector3.Angle()作用是一样的。三、Euler声明形式:public static Quaternion Euler ( float x, float y, float z ) 或者: public static Quaternion Euler ( Vector3 euler )这个函数可以将一个欧拉形式的旋转转换成四元数形式的旋转。传入的参数分别是欧拉轴上的转动角度。四、Slerp声明形式:public static Quaternion Slerp ( Quaternion from, Quaternion to, float t )基本意思就是线性地从一个角度旋转到另一个角度,其中,旋转匀速增加t。
附加内容:很多时候from 和to都不是固定的,而且上一个脚本也不能保证所有角度下的旋转速度一致。所以我写了这个脚本来保证可以应付大多数情况。
Transform target; float rotateSpeed = 30.0f; Quaternion wantedRotation = Quaternion.FromToRotation(transform.position, target.position); float t = rotateSpeed/Quaternion.Angle(transform.rotation, wantedRotation)*Time.deltaTime; transform.rotation = Quaternion.Slerp(transform.rotation, target.rotation, t);这个脚本可以保证物体的旋转速度永远是rotateSpeed。如果自身坐标和目标之间的夹角是X度,我们想以s=30度每秒的速度旋转到目标的方向,则每秒旋转的角度的比例为s/X。 再乘以每次旋转的时间Time.deltaTime我们就得到了用来匀速旋转的t。五、FromToRotation声明形式:public static Quaternion FromToRotation ( Vector3 from, Vector3 to )它是得到从一个方向到另一个方向的旋转。就是转一个方向,就这么简单。六、identity这个不是一个函数,它是一个只读的变量。它代表世界坐标系或者父物体坐标系中的无旋转方位。
转载地址:http://cjrxo.baihongyu.com/