一.歐拉角
歐拉角最容易表示,用三個變量X,Y,Z可以直觀的表示繞着某個軸的旋轉角度。
在Unity里就是Transform組件的Rotation里的X Y Z三個變量代表了歐拉角
二.四元數
四元數相比於歐拉角就比較復雜了,由四個變量組成(在Unity中稱為X,Y,Z,W),但是這些變量的值不代表旋轉角度,所以可能給你一個向量(0。7,0,0,0.7)你並不知道實際旋轉的角度,當然四元數的詳細解釋需要數學方面的深入研究,有興趣的可以自行查找有關資料
因為在Unity沒有可視化界面可以調整四元數(因為真的調了也不直觀看到旋轉的角度),所以我們只能用腳本來訪問
三.腳本中內容
歐拉角如果在腳本中表示呢?
是不是想到之前圖中的那個Rotation,那你是不是自然而然的想到了通過transform.rotation訪問呢?如果你是這樣想的,那就錯了!
在Unity中transform.rotation代表的是四元數!附上官網證明!
那到底如何表示歐拉角呢?其實表示很簡單,並附上官網解釋
transform.eulerAngles =new Vector3(20,300,40);
1
當我們以上述代碼運行后會發現Rotation中的Y值是-60,那是因為面板上的Rotation中的X Y Z值范圍是在(-180,180),對於代碼中超出的部分會自動進行計算映射到范圍內
四元數的代碼表示就是之前的transform.rotation,那你肯定會想歐拉角和四元數之前能否轉換呢,知道其中一個的值,如果改變成對方呢?代碼如下
//歐拉角->四元數
//通過Quaternion.Euler() 傳遞一個Vector3向量的歐拉角
transform.rotation = Quaternion.Euler(new Vector3(20, 300, 40));
//四元數->歐拉角
transform.rotation.eulerAngles;//對你沒看錯 直接可以轉換獲取
1
2
3
4
5
6
三.區別
歐拉角:
優點:三個角度組成,直觀,容易理解
優點:可以進行從一個方向到另一個方向旋轉大於180度的角度
缺點:死鎖問題——萬向節死鎖 萬向節死鎖介紹
四元數
優點:不存在萬向節死鎖問題
優點:存儲空間小,計算效率高
缺點:單個四元數不能表示在任何方向上超過180度的旋轉。
缺點:數字表示不直觀
四.常用API
Quaternion.LookRotation() 使其轉向某個方向
函數傳遞的參數的一個Vector3的向量 這個向量表示的是要看向的向量,通常用目標的positon和自身的position進行相減求得此向量
Vector3 pos = target.transform.position - transform.position;
transform.rotation = Quaternion.LookRotation(pos);
1
2
是不是覺得和transform.LookAt()效果很像…
//和上面代碼得到的效果相同
transform.LookAt(target.transform);
1
2
Quaternion.Slerp() 平滑進行轉動動畫
函數傳遞的參數分別是 當前GameObject的四元數、目標要轉向的四元數 和 一個插值時間
我們看個例子
void LookAtTarget()
{
if (Input.GetKey(KeyCode.Space))
{
Vector3 dir = target.transform.position - transform.position;
dir.y = 0;//不讓Player有y軸上的傾角
Quaternion target = Quaternion.LookRotation(dir);
transform.rotation = Quaternion.Slerp(transform.rotation, target, Time.deltaTime);
}
}
1
2
3
4
5
6
7
8
9
10
我們將上述的LookAtTarget()方法放到Update()函數中進行執行
就可以看到平滑的轉動
Quaternion.Lerp() 說實話個人用起來和Slerp()區別不大
圖中紅線框出來的就是區別:使用Lerp()進行旋轉的速度較快,但是在旋轉角度較大的時候,效果會糟一點。
Quaternion.RotateTowards()
傳遞兩個四元數,和一個角度增量值,使第一個四元數逐漸趨近於第二個四元數並最終相等
void Update()
{
float step = 3 * Time.deltaTime;
transform.rotation = Quaternion.RotateTowards(transform.rotation,target.transform.rotation,step);
}
1
2
3
4
5
結果就是當前物體的四元數和目標的四元數相等
Transform.RotateAround()
傳遞一個參照點point、繞哪個軸轉axis和增量角度angle
void Update(http://www.my516.com)
{
float step = 3 * Time.deltaTime;
transform.RotateAround(target.transform.position,Vector3.up,step);
}
1
2
3
4
5
五.總結
差不多基礎概念就這些了吧,如果要深入了解的話,建議還是看API,並且自己多動手嘗試一下數據~
---------------------