为了平滑游戏对象在 Unity 中的行进路线,我们经常会在 Unity 中使用 ITweenPath 插件,但有时候我们或许只会使用到通过 ITweenPath 绘制出来的点(比如把这些点放到配置文件中),并不希望加载 ITweenPath 插件或者通过自己的函数去实现游戏对象的移动,通过查看 ITweenPath 的代码,很容易就把 ITweenPath 绘制曲线点的方法给提取出来了,主函数并不多,只有三个方法,希望能给你带来帮助!
先来看看最终的 Demo 实现方式:
Demo 代码:
1. </blockquote></div>
2. <div class="blockcode"><blockquote>using UnityEngine;using System.Collections.Generic;
3. public class PointPath : MonoBehaviour {
4. private Vector3[] pathList;
5. public GameObject sphere;
6. public GameObject path;
7. void Awake()
8. {
9. Transform[] transformList = path.GetComponentsInChildren<Transform> ();
10. int length = transformList.Length;
11. pathList = new Vector3[length];
12.
13. for (int index = 0; index < length; index ++)
14. {
15. pathList[index] = transformList[index].transform.position;
16. }
17.
18. Vector3[] resultList = PointController.PointList (this.pathList, 20);
19.
20. foreach (Vector3 point in resultList)
21. {
22.
23. GameObject gameObject = (GameObject)Instantiate(sphere);
24. gameObject.transform.localPosition = point;
25. gameObject.transform.localScale = new Vector3(0.5f, 0.5f, 0.5f);
26. }
27. }
28. PointController.cs
29.
30. using UnityEngine;
31. using System;
32. using System.Collections;
33. public class PointController{
34.
35. /// <summary>
36. /// 获取曲线上面的所有点
37.
38. /// </summary>
39.
40. /// <returns>The list.</returns>
41. /// <param name="path">需要穿过的点列表</param>
42.
43. /// <param name="pointSize">两个点之间的节点数量</param>
44. public static Vector3[] PointList(Vector3[] path, int pointSize)
45. {
46.
47. Vector3[] controlPointList = PathControlPointGenerator(path);
48. int smoothAmount = path.Length * pointSize;
49.
50. Vector3[] pointList = new Vector3[smoothAmount];
51. for (int index = 1; index <= smoothAmount; index++)
52. {
53.
54. Vector3 currPt = Interp(controlPointList, (float) index / smoothAmount);
55. pointList[index - 1] = currPt;
56.
57.
58. }
59. return pointList;
60.
61.
62. }
63. /// <summary>
64.
65.
66. /// 获取控制点
67. /// </summary>
68. /// <returns>The control point generator.</returns>
69. /// <param name="path">Path.</param>
70.
71.
72. private static Vector3[] PathControlPointGenerator(Vector3[] path)
73. {
74. int offset = 2;
75.
76.
77. Vector3[] suppliedPath = path;
78.
79.
80. Vector3[] controlPoint = new Vector3[suppliedPath.Length + offset];
81.
82.
83. Array.Copy(suppliedPath, 0, controlPoint, 1, suppliedPath.Length);
84.
85.
86. controlPoint[0] = controlPoint[1] + (controlPoint[1] - controlPoint[2]);
87.
88.
89. controlPoint[controlPoint.Length - 1] = controlPoint[controlPoint.Length - 2] + (controlPoint[controlPoint.Length - 2] - controlPoint[controlPoint.Length - 3]);
90.
91.
92. if(controlPoint[1] == controlPoint[controlPoint.Length - 2])
93. {
94. Vector3[] tmpLoopSpline = new Vector3[controlPoint.Length];
95.
96.
97. Array.Copy(controlPoint, tmpLoopSpline, controlPoint.Length);
98.
99.
100. tmpLoopSpline[0] = tmpLoopSpline[tmpLoopSpline.Length - 3];
101.
102.
103. tmpLoopSpline[tmpLoopSpline.Length - 1] = tmpLoopSpline[2];
104.
105.
106. controlPoint = new Vector3[tmpLoopSpline.Length];
107.
108.
109. Array.Copy(tmpLoopSpline, controlPoint, tmpLoopSpline.Length);
110. }
111. return(controlPoint);
112. }
113. /// <summary>
114. /// 根据 T 获取曲线上面的点位置
115. /// </summary>
116.
117.
118. /// <param name="pts">Pts.</param>
119. /// <param name="t">T.</param>
120.
121.
122. private static Vector3 Interp(Vector3[] pts, float t)
123. {
124. int numSections = pts.Length - 3;
125. int currPt = Mathf.Min(Mathf.FloorToInt(t * (float) numSections), numSections - 1);
126.
127.
128. float u = t * (float) numSections - (float) currPt;
129.
130.
131. Vector3 a = pts[currPt];
132.
133.
134. Vector3 b = pts[currPt + 1];
135. Vector3 c = pts[currPt + 2];
136. Vector3 d = pts[currPt + 3];
137.
138.
139. return .5f * ( (-a + 3f * b - 3f * c + d) * (u * u * u) + (2f * a - 5f * b + 4f * c - d) * (u * u) + (-a + c) * u + 2f * b );
140. }
141. }
希望本文章对大家有所帮助...