【Unity】6.7 向量和Vector3類

分類:Unity、C#、VS2015 數組

建立日期:2016-04-20 學習

1、簡介

在虛擬的遊戲世界中,與3D有關的數學知識決定了遊戲引擎如何計算和模擬出開發者以及玩家看到的每一幀畫面。學習或者回想一下基礎的3D有關的數學知識,能夠幫助開發者對遊戲引擎產生更深入的瞭解。 動畫

2、向量

在數學中向量的定義是:既有大小又有方向的量叫做向量。在空間中,向量能夠用一段有方向的線段來表示。 spa

向量在遊戲開發過程當中的應用十分普遍,可用於描述具備大小和方向兩個屬性的物理量,例如物體運動的速度、加速度、攝像機觀察方向、剛體受到的力等都是向量,所以向量是物理、動畫、三維圖形的基礎。 設計

一、向量相關概念

·模:向量的長度。 3d

·標準化(Normalizing):保持方向不變,將向量的長度變爲1。 code

·單位向量:長度爲1的向量。 orm

·零向量:各份量均爲0的向量。 對象

二、向量的運算 blog

(1)加減

向量的加法(減法)爲各份量分別相加(相減)。在物理上能夠用來計算兩個力的臺力,或者幾個速度份量的疊加。

image

(2)數乘

向量與一個標量相乘稱爲數乘。數乘能夠對向量的長度進行縮放,若是標量大於0,那麼向量的方向不變;若標量小於0,則向量的方向會變爲反方向。

(3)點乘

兩個向量點相乘獲得一個標量,數值等於兩個向量長度相乘後再乘以兩者夾角的餘弦值。若是兩個向量a,b均爲單位向量,那麼a.b等於向量b在向量a方向上的投影的長度(也等於向量a在向量b方向的投影)

image

經過兩個向量點乘結果的符號能夠快速地判斷兩個向量的夾角狀況:

若u·v = 0,則向量u、v相互垂直。

若u·v > 0,則向量u、v夾角小於90°。

若u·v <0,則向量u、v夾角大於90°。

(4)叉乘

兩個向量的叉乘獲得一個新的向量,新向量垂直於原來的兩個向量,並旦長度等於原向量長度相乘後再乘夾角的正弦值。

image

能夠經過左手擺出上圖所示的手勢來判斷叉乘結果的方向(使用左手是由於Unity裏用的是左手座標系)。假設有向量Result=a×b,將拇指朝向a的方向,食指指向b的方向,則中指指向的方向爲叉乘結果的方向。

注意:叉乘不知足交換律,即a× b≠ b× a。

3、Vector3類

在Unity中,和向量有關的類有Vector二、Vector三、Vector4,分別對應不一樣維度的向量,其中Vector3的使用最爲普遍。

一、成員變量和方法

Vector3類的經常使用成員變量和方法以下:

x、y、z:向量的X份量、Y份量、Z份量。

normalized:獲取單位化後的向量(只讀)。

magnitude:獲取向量長度(只讀)。

sqrMagnitude獲取向量長度的平方(只讀)。

Cross():向量叉乘。

Dot():向量點乘。

Project():計算向量在另外一向量上的投影。

Angle():返回兩個向量之間的夾角。

Distance():返回兩個向量之間的距離。

運算符:+、-、*、/、==、!=

下面是Vector3類的—些應用示例。

二、示例1(Demo7_1_DistanceTest.unity)

該例子演示瞭如何計算兩個位置之間的距離。其中other變量綁定的遊戲對象的座標爲(50,50,50),腳本綁定的目標對象的座標爲(-2,-3.3,-10)。

在Distance.unity場景中使用了本示例的源文件,運行效果以下:

image

下面是該場景中使用的C#腳本代碼(DistanceTest.cs文件):

using UnityEngine;
using System.Collections;
public class DistanceTest : MonoBehaviour
{
    public Transform other;
    void Start()
    {
        if (other != null)
        {
            var dist = Vector3.Distance(other.position, transform.position);
            print("Distance to other: " + dist);
        }
    }
}

三、示例2(Demo7_2_DirectionMove.unity)

該例子演示如何讓遊戲對象沿着指定的方向移動。

DirectionMove.cs的代碼以下:

using UnityEngine;
using System.Collections;
public class DirectionMove : MonoBehaviour
{
    public Vector3 direction = Vector3.forward;//移動方向
    public float speed = 5.0f;//速度

    void Update()
    {
        transform.position += direction * speed * Time.deltaTime;
    }
}

四、示例3(Demo7_3_SqrMagnitude.unity)

該例子演示如何利用Vector3.sqrMagnitude來判斷目標對象的距離是否小於觸發距離,其中other變量的座標爲(-2,-3,-10),該腳本綁定的遊戲對象的座標爲(-2,-3.3,-10)。

使用的腳本(SqrMagnitude.cs文件)代碼以下:

using UnityEngine;
using System.Collections;
public class SqrMagnitude : MonoBehaviour
{
    public Transform other;   //目標物體的Transform
    public double closeDistance = 5.0;  // 觸發距離
    void Update()
    {
        if (other)
        {
            var sqrLen = (other.position - transform.position).sqrMagnitude;
            // 使用Vector3.sqrMagnitude比Vector3.magnitude計算速度要快
            if (sqrLen < closeDistance * closeDistance)
            {
                print("目標物體已靠近!");
            }
        }
    }
}

五、示例4(Demo7_4_MoveToTarget.unity)

該例子演示對象從初始點平滑移動到目標點的動畫,其中start變量綁定的對象座標爲(-3,-3,-10),end變量綁定的座標爲(-3,-3,20)。

使用的腳本(MoveToTarget.cs文件)代碼以下:

using UnityEngine;
using System.Collections;
public class MoveToTarget : MonoBehaviour
{
    public Transform start; //初始位置
    public Transform end; //終點位置
    void Update()
    {
        transform.position = Vector3.Lerp(start.position, end.position, Time.time);
    }
}

六、示例5(Demo7_5_SunRiseAndDown.unity)

該例子演示如何利用Slerp插值方法模擬太陽升起和落下的過程。

使用的腳本(SunRiseAndDown.cs文件)代碼以下:

using UnityEngine;
using System.Collections;
public class SunAndRise : MonoBehaviour
{
    public Transform sunrise;//升起位置
    public Transform sunset; //落下位置 
    public float journeyTime = 10.0f; //從升起到落下須要的時間,以秒爲單位
    private float startTime; //用於記錄開始的時間

    void Start()
    {
        startTime = Time.time; // 設置開始的時間
    }

    void Update()
    {
        var center = (sunrise.position + sunset.position) * 0.5f;//計算運行軌跡的圓心點
        center -= new Vector3(0, 1, 0);
        var riseRelCenter = sunrise.position - center;//升起位置到圓心的向量
        var setRelCenter = sunset.position - center; //落下位置到圓心的向量
        var fracComplete = (Time.time - startTime) / journeyTime;//計算用於插值的係數
        transform.position = Vector3.Slerp(riseRelCenter, setRelCenter, fracComplete);//Slerp插值
        transform.position += center;
    }
}

下面是該例子的運行效果:

image

4、矩陣

相向量同樣,矩陣也是3D數學中十分重要基礎。

一、矩陣的概念

m× n的矩陣是一個具備m行、n列的矩形數組,行數和列數分別爲矩陣的維度。在遊戲引擎中使用的矩陣一般爲4×4矩陣,由於它能夠描述向量的平移、旋轉、縮放等全部的線性變換。

二、矩陣的計算

本身看其餘參考資料吧。

三、Matrix4x4類

Unity使用Matrix4x4類來描述4×4矩陣。

更多介紹請參看其餘參考資料。

5、奇次座標

在3D數學中,齊次座標就是將本來3維的向量(x,y,z)用4維向量(wx,wy,wz,w)來表示。引入齊次座標的主要有以下目的:

一、可更好地區分向量和點。在三維空間中, (x,y,z)既能夠表示點也能夠表示份量,不便於區分,若是引入齊次座標,則可使用(x,y,z,1)來表示座標點,使用(x,y,z,0)來表示向量。

二、統—用矩陣乘法表示平移、旋轉、縮放變換。若是使用3×3的矩陣,矩陣乘法只能表示旋轉和縮放變換,沒法表示平移變換。而在4D齊次空間中,可使用4×4的齊次矩陣來統一表示平移、旋轉、縮放變換。

三、當份量w=0時能夠用來表示無窮遠的點。

齊次座標是計算機圖形學中一個很是重要的概念,可是在Unity中不多須要直接和它打交道,在編寫一些shader可能會用到它,平時在腳本中主要仍是使用三維向量Vector3。Unity經過便利的接口設計將這一重要概念隱藏在了引擎後面。

相關文章
相關標籤/搜索