最近爲了模擬法術的運行軌跡,打算使用了貝塞爾曲線,以前在 2D 開發項目中也經常使用貝塞爾曲線,但是在 3D 場景中貝塞爾曲線的實現還是稍稍有些麻煩,於是在網上收集 Unity3D 貝塞爾曲線的代碼,原文鏈接:http://www.xuanyusong.com/archives/1548
Demo 過程如下:
示例代碼:
01 |
using UnityEngine; |
02 |
using System.Collections; |
03 |
04 |
public class BezierPath
: MonoBehaviour |
05 |
{ |
06 |
public GameObject
sphere; |
07 |
08 |
public GameObject
begin; |
09 |
public GameObject
control0; |
10 |
public GameObject
control1; |
11 |
public GameObject
end; |
12 |
13 |
void Awake() |
14 |
{ |
15 |
Bezier
bezier = new Bezier
(begin.transform.position, control0.transform.position, control1.transform.position, end.transform.position); |
16 |
17 |
int pointSize
= 20; |
18 |
Vector3[]
resultList = new Vector3[pointSize]; |
19 |
20 |
for ( int index
= 1; index <= pointSize; index ++) |
21 |
{ |
22 |
resultList[index
- 1] = bezier.GetPointAtTime(( float )index
/ ( float )pointSize); |
23 |
} |
24 |
25 |
foreach (Vector3
point in resultList) |
26 |
{ |
27 |
GameObject
gameObject = (GameObject)Instantiate(sphere); |
28 |
gameObject.transform.localPosition
= point; |
29 |
gameObject.transform.localScale
= new Vector3(0.5f,
0.5f, 0.5f); |
30 |
} |
31 |
} |
32 |
} |
01 |
using UnityEngine; |
02 |
03 |
public class Bezier |
04 |
{ |
05 |
public Vector3
p0; |
06 |
public Vector3
p1; |
07 |
public Vector3
p2; |
08 |
public Vector3
p3; |
09 |
|
10 |
private Vector3
b0 = Vector3.zero; |
11 |
private Vector3
b1 = Vector3.zero; |
12 |
private Vector3
b2 = Vector3.zero; |
13 |
private Vector3
b3 = Vector3.zero; |
14 |
|
15 |
private float Ax; |
16 |
private float Ay; |
17 |
private float Az; |
18 |
|
19 |
private float Bx; |
20 |
private float By; |
21 |
private float Bz; |
22 |
|
23 |
private float Cx; |
24 |
private float Cy; |
25 |
private float Cz; |
26 |
|
27 |
///
<summary> |
28 |
///
構造函數 |
29 |
///
</summary> |
30 |
///
<param name="v0">起始點</param> |
31 |
///
<param name="v1">第一個控制點</param> |
32 |
///
<param name="v2">第二個控制點(通過可省略,有 Vector3.Zero 代碼)</param> |
33 |
///
<param name="v3">結束點</param> |
34 |
public Bezier(
Vector3 v0, Vector3 v1, Vector3 v2, Vector3 v3 ) |
35 |
{ |
36 |
this .p0
= v0; |
37 |
this .p1
= v1; |
38 |
this .p2
= v2; |
39 |
this .p3
= v3; |
40 |
} |
41 |
|
42 |
///
<summary> |
43 |
///
通過 t 獲取節點 |
44 |
///
</summary> |
45 |
///
<returns>The point at time.</returns> |
46 |
///
<param name="t">t 的取值範圍在 0.0 >= t <= 1.0</param> |
47 |
public Vector3
GetPointAtTime( float t
) |
48 |
{ |
49 |
this .CheckConstant(); |
50 |
51 |
float t2
= t * t; |
52 |
float t3
= t * t * t; |
53 |
float x
= this .Ax
* t3 + this .Bx
* t2 + this .Cx
* t + p0.x; |
54 |
float y
= this .Ay
* t3 + this .By
* t2 + this .Cy
* t + p0.y; |
55 |
float z
= this .Az
* t3 + this .Bz
* t2 + this .Cz
* t + p0.z; |
56 |
return new Vector3(
x, y, z ); |
57 |
} |
58 |
|
59 |
private void SetConstant() |
60 |
{ |
61 |
this .Cx
= 3f * ( ( this .p0.x
+ this .p1.x
) - this .p0.x
); |
62 |
this .Bx
= 3f * ( ( this .p3.x
+ this .p2.x
) - ( this .p0.x
+ this .p1.x
) ) - this .Cx; |
63 |
this .Ax
= this .p3.x
- this .p0.x
- this .Cx
- this .Bx; |
64 |
this .Cy
= 3f * ( ( this .p0.y
+ this .p1.y
) - this .p0.y
); |
65 |
this .By
= 3f * ( ( this .p3.y
+ this .p2.y
) - ( this .p0.y
+ this .p1.y
) ) - this .Cy; |
66 |
this .Ay
= this .p3.y
- this .p0.y
- this .Cy
- this .By; |
67 |
this .Cz
= 3f * ( ( this .p0.z
+ this .p1.z
) - this .p0.z
); |
68 |
this .Bz
= 3f * ( ( this .p3.z
+ this .p2.z
) - ( this .p0.z
+ this .p1.z
) ) - this .Cz; |
69 |
this .Az
= this .p3.z
- this .p0.z
- this .Cz
- this .Bz; |
70 |
} |
71 |
72 |
private void CheckConstant() |
73 |
{ |
74 |
if ( this .p0
!= this .b0
|| this .p1
!= this .b1
|| this .p2
!= this .b2
|| this .p3
!= this .b3
) |
75 |
{ |
76 |
this .SetConstant(); |
77 |
|
78 |
this .b0
= this .p0; |
79 |
this .b1
= this .p1; |
80 |
this .b2
= this .p2; |
81 |
this .b3
= this .p3; |
82 |
} |
83 |
} |
84 |
} |