【Unity】6.8 Quaternion类(四元数)

分类:Unity、C#、VS2015 ide

建立日期:2016-04-20 函数

1、四元数的概念

四元数包含一个标量份量和—个三维向量份量,四元数Q能够记做: spa

Q=[w,(x,y,z)] code

在3D数学中使用单位四元数来表示旋转,对于三维空间中旋转轴为n,旋转角度为a的旋转,若是用四元数表示,四个份量分别为: orm

w=cos(a/2) 对象

x=sin(a/2)cos(bx) blog

y=sin(a/2)cos(by) 游戏

z=sin(a/2)cos(bz) 开发

其中bx、by、bz分别为旋转轴的x,y,z份量。 get

从上面的描述中能够看到四元数表示的旋转并不直观。另外,还能够用欧拉角和矩阵表示旋转。可是每—种表示方法都有真各自的优缺点,下图简单地对这3种旋转的表示方法进行了对比:

image

因为3种表示旋转的方法都有各自的优缺点,因此在开发过程当中须要根据实际需求选择不一样的方法。

2、Quaternion类

在Unity中,四元数使用Quaternion类来表示。

下图是Quaternion类提供的变量:

image

下图是Quaternion类提供的函数:

image

下面的C#代码演示了如何让某个游戏对象(好比Cube)绕Y轴自转:

float rotateSpeed = 50f; //设置绕y轴自转的速度

void Update()

{

//绕y轴自转

transform.rotation =Quaternion.Euler(0f,rotateSpeed*Time.time,0);

}

3、示例

Transform.rotation为对象在世界坐标系下的旋转,Transform.localRotation为对象在父对象的局部坐标系下的旋转,这两个变量的结果类型均为四元数。所以,只要将四元数的结果赋值给这两个变量(Transform.rotation或者Transform.localRotation),就能够设置游戏对象的旋转了。

下面经过一些例子说明经过四元数控制旋转的基本用法。

一、示例1(Demo8_1_ToAngleAxis.unity)

该例子演示如何获得游戏对象当前旋转的角度-轴。

例子中使用的脚本(AngleAxis.cs)以下:

using UnityEngine;
using System.Collections;
public class ToAngleAxis : MonoBehaviour
{
    public float angle = 0.0f;// 旋转角度
    public Vector3 axis = Vector3.zero;//旋转轴
    void Start()
    {
        transform.rotation.ToAngleAxis(out angle, out axis);
        print(angle);
        print(axis);
    }
}

效果以下图所示:

image

二、示例2(Demo8_2_QuaternionExample.unity)

下面一行代码演示了如何先将游戏对象的旋转归零:

transform.rotation = Quaternion.identity;

归零后,局部坐标系的坐标轴与世界坐标系的坐标轴是平行的。

该例子把前面的例子综合起来,实现了模拟器太阳升起和落下的过程,同时让对象的前方向朝着target,上方向朝着Vector.up。

效果以下:

image

三、示例3(Demo8_3_CameraLookAt.unity)

该例子将对象的旋转从from平滑插值到to,以此来模拟摄像机的观察方向从物体a过滤到物体b的效果。

代码以下(CameraLookAt.cs文件):

using UnityEngine;
using System.Collections;

public class CameraLookAt : MonoBehaviour
{
    public Transform from;
    public Transform to;

    //相机观察方向从a过渡到b所需的时间,以秒为单位
    public float tranTime = 20.0f;

    //用于记录开始的时间
    private float startTime;

    void Start()
    {
        startTime = Time.time; // 设置开始时间
    }

    void Update()
    {
        //计算用于插值的系数
        var fracComplete = (Time.time - startTime) / tranTime;
        //平滑插值
        transform.rotation = Quaternion.Slerp(from.rotation, to.rotation, fracComplete);
    }

    Transform[] spawnPoints;


}
相关文章
相关标签/搜索