Unity3D Quaternion各屬性和函數測試

Quaternion屬性與方法

一,屬性:

x、y、z就不說了,只看一個eulerAngles,代碼如下:

[C#] 純文本查看 複製代碼
?
1
2
3
4
5
6
7
8
public Quaternion rotation = Quaternion.identity;
 
void Start()
{
rotation.eulerAngles = new Vector3(0, 30, 0);
transform.rotation = rotation;
print(rotation.eulerAngles.y);
}


效果:將物體繞y軸順時針轉30°,效果與transform.eulerAngles相同。物體rotation = (0,30,0)。但是不能直接爲transform.rotation.eulerAngle賦值。

二,方法

1,function ToAngleAxis (out angle :float, out axis :Vector3) :void

[C#] 純文本查看 複製代碼
?
1
2
3
4
5
6
7
8
9
public float angle = 0.0F;
public Vector3 axis = Vector3.zero;
 
void Start()
{
transform.eulerAngles = new Vector3(0, 90, 0);
transform.rotation.ToAngleAxis(out angle, out axis);
print(angle + " " + axis);
}


效果:將物體的旋轉角度返回到angles和axis裏(物體的z軸和世界座標z軸的夾角)。
輸入:transform.localEulerAngles=(0,0,0);
輸出:angle=0, axis=(1,0,0);
輸入:transform.localEulerAngles=(0,90,0);
輸出:angle=90,axis=(0,1,0);
輸入:transform.localEulerAngles=(270,0,0);
輸出:angle=90,axis=(-1,0,0)

2,function SetFromToRotation (fromDirection :Vector3, toDirection :Vector3) :void

[C#] 純文本查看 複製代碼
?
01
02
03
04
05
06
07
08
09
10
11
private Vector3 _from = Vector3.one;
private Vector3 _to = new Vector3(100f, 200f, 100f);
private Quaternion q;
private Vector3 headUpDir;
 
void Start()
{
q.SetFromToRotation(_from, _to);
transform.rotation=q;
headUpDir=transform.TransformDirection(Vector3.forward);
}


效果:把物體的fromDirection旋轉到toDirection
輸入:a=Vector3(0,0,1); b=Vector3(0,1,0)//把z軸朝向y軸
輸出: q=(-0.7,0,0,0.7); headUpDir=(0,1,0)
輸入:a=Vector3(0,0,1); b=Vector3(1,0,0)//把z軸朝向x軸
輸出: q=(0,0.7,0,0.7); headUpDir=(1,0,0)
輸入:a=Vector3(0,1,0); b=Vector3(1,0,0)//把y軸朝向x軸
輸出: q=(0,0,-0.7,0.7); headUpDir=(0,0,1)

3,function SetLookRotation (view : Vector3, up : Vector3 = Vector3.up) : void

[C#] 純文本查看 複製代碼
?
1
2
3
4
5
6
7
8
9
public Transform obj1;
public Transform obj2;
Quaternion q;
 
void Update()
{
q.SetLookRotation(obj1.position, obj2.position);
transform.rotation = q;
}


效果:類似於LookAt()方法,使物體1始終注視着物體2

4, static operator * (lhs : Quaternion, rhs : Quaternion) : Quaternion

[C#] 純文本查看 複製代碼
?
1
2
3
4
5
6
public Transform extraRotation;
 
void Update()
{
transform.rotation *= extraRotation.rotation;
}


效果:組合旋轉lhs和rhs。旋轉一個點,首先用lhs,然後用rhs旋轉,與使用組合旋轉相同。注意旋轉不可交換: lhs*rhs不等於rhs*lhs。 我理解旋轉的角度就是將*號兩邊的角度加起來。

5,static operator * (rotation : Quaternion, point : Vector3) : Vector3

[C#] 純文本查看 複製代碼
?
1
2
3
4
5
6
7
Vector3 relativeDirection = Vector3.forward;
Vector3 absoluteDirection;
 
void Update () {
absoluteDirection = transform.rotation * relativeDirection;
transform.position += absoluteDirection * Time.deltaTime;
}


效果:將一個向量根據rotation旋轉到另一個向量。

6,static function Dot (a : Quaternion, b : Quaternion) : float
效果:將兩個Quaternion點乘,返回一個float值,意義待補充。

7,static function AngleAxis (angle : float, axis : Vector3) : Quaternion 

[C#] 純文本查看 複製代碼
?
1
2
3
void Start(){
        transform.rotation = Quaternion.AngleAxis(30, Vector3.up);
}


效果:將物體繞axis旋轉angle度。

8,static function FromToRotation (fromDirection :Vector3, toDirection :Vector3) : Quaternion 

[C#] 純文本查看 複製代碼
?
1
transform.rotation = Quaternion.FromToRotation(Vector3.up, transform.forward);


效果:跟SetFromToRotation差不多,區別是可以返回一個Quaternion。通常用來讓transform的一個軸向(例如 y軸)與toDirection在世界座標中同步。

9,static function LookRotation (forward :Vector3, upwards :Vector3 =Vector3.up) : Quaternion
效果:跟SetLootRotation差不多,區別是可以返回一個Quaternion。

10,static function Slerp (from : Quaternion, to : Quaternion, t :float) : Quaternion 

[C#] 純文本查看 複製代碼
?
1
2
3
4
5
6
public Transform from;
public Transform to;
public float speed = 0.1F;
void Update() {
    transform.rotation = Quaternion.Slerp(from.rotation, to.rotation, Time.time * speed);
}


效果:球面插值,插值不是等角速度的,而是變速的。 會有越來越慢的感覺。

11,static function Lerp (from : Quaternion, to : Quaternion, t :float) : Quaternion 

效果:與Slerp效果差不多,效率比Slerp高但是如果from和to相差過大效果會不好,會返回一個標準化的Quaternion。

12,static function RotateTowards (from : Quaternion, to : Quaternion, maxDegreesDelta :float) : Quaternion

效果:旋轉一個角度從from向to。與Slerp基本相同,但這個函數的角速度永遠不會超過maxDegreesDelta。負的maxDegreesDelta值將使旋轉遠離to。

13,static function Inverse (rotation : Quaternion) : Quaternion 

效果:返回反向的旋轉。

14,static function Angle (a : Quaternion, b : Quaternion) :float

[C#] 純文本查看 複製代碼
?
1
2
3
4
public Transform target;
void Update(){
     float angle = Quaternion.Angle(transform.rotation, target.rotation);
}


效果:返回a和b兩者之間的角度。

15,static function Euler (x :float, y :float, z :float) : Quaternion 

[C#] 純文本查看 複製代碼
?
1
public Quaternion rotation = Quaternion.Euler(0, 30, 0);


效果:把旋轉角度變成對應的Quaternion。

三,實例

[C#] 純文本查看 複製代碼
?
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
var target : Transform;
var edgeBorder = 0.1;
var horizontalSpeed = 360.0;
var verticalSpeed = 120.0;
var minVertical = 20.0;
var maxVertical = 85.0;
 
private var x = 0.0;
private var y = 0.0;
private var distance = 0.0;
 
function Start()
{
    x = transform.eulerAngles.y;
    y = transform.eulerAngles.x;
    distance = (transform.position - target.position).magnitude;
}
 
function LateUpdate()
{
    var dt = Time.deltaTime;
    x -= Input.GetAxis("Horizontal") * horizontalSpeed * dt;
    y += Input.GetAxis("Vertical") * verticalSpeed * dt;
     
    y = ClampAngle(y, minVertical, maxVertical);
      
    var rotation = Quaternion.Euler(y, x, 0);
    var position = rotation * Vector3(0.0, 0.0, -distance) + target.position;
    //print(rotation + " && " + rotation * Vector3(0.0, 0.0, -distance));
    transform.rotation = rotation;
    transform.position = position;
}
 
static function ClampAngle (angle : float, min : float, max : float) {
    if (angle < -360)
        angle += 360;
    if (angle > 360)
        angle -= 360;
    return Mathf.Clamp (angle, min, max);
}


非常有意思的一個例子,來自unity官方工程ShadowDemoProject,效果是可以通過鍵盤使攝像機圍繞一點自由旋轉,類似於在一個球面上運動。

[C#] 純文本查看 複製代碼
?
1
var position = rotation * Vector3(0.0, 0.0, -distance) + target.position;


這一句非常有意思,也很難理解,完全理解了這一句後,Quaternion在你手裏會變的非常強大!
發佈了30 篇原創文章 · 獲贊 12 · 訪問量 13萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章