Quaternion

01:欧拉角
Quaternion_第1张图片

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. 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组件方法

欧拉角,Unity中没有专门的API,所以这里我们用transform和rigidbody相关的API进行讨论。
Quaternion_第2张图片
Quaternion_第3张图片
Quaternion_第4张图片

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));
       
    }

Quaternion_第5张图片

四元数的常用API
Quaternion_第6张图片
Quaternion_第7张图片
Quaternion_第8张图片
Quaternion_第9张图片
Quaternion_第10张图片
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

这个不是一个函数,它是一个只读的变量。它代表世界坐标系或者父物体坐标系中的无旋转方位。

你可能感兴趣的:(unity)