一,屬性:
x、y、z就不說了,只看一個eulerAngles,代碼如下:
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
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
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
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
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
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
1
2
3
|
void
Start(){ transform.rotation
= Quaternion.AngleAxis(30, Vector3.up); } |
效果:將物體繞axis旋轉angle度。
8,static function FromToRotation (fromDirection :Vector3, toDirection :Vector3) : Quaternion
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
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
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
1
|
public
Quaternion rotation = Quaternion.Euler(0, 30, 0); |
效果:把旋轉角度變成對應的Quaternion。
三,實例
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,效果是可以通過鍵盤使攝像機圍繞一點自由旋轉,類似於在一個球面上運動。
1
|
var
position = rotation * Vector3(0.0, 0.0, -distance) + target.position; |
這一句非常有意思,也很難理解,完全理解了這一句後,Quaternion在你手裏會變的非常強大!