2using System.Collections.Generic;
21 [SerializeField]
public Transform[]
_items =
new Transform[0];
24 [SerializeField]
private RouteType _routeType;
26 [SerializeField]
private bool _circuit =
true;
28 [Range(0.0f, 100.0f)] [SerializeField]
private float _entryDistance = 2f;
30 [Range(0.0f, 100.0f)] [SerializeField]
private float _exitDistance = 2f;
32 [Range(4, 50)] [SerializeField]
private int _curveSmoothing = 50;
34 [Range(4, 50)] [SerializeField]
private int _curveSmoothingInternal = 10;
36 [SerializeField]
private bool _isAlwaysDraw;
38 private float _length;
39 private int _numPoints;
40 private Vector3[] _points;
41 private float[] _distances;
42 private Vector3 _curveStartPoint;
43 private Vector3 _curveEndPoint;
68 set => _circuit = value;
77 if (WaypointData.Length > 1) CachePositionsAndDistances();
79 _numPoints = WaypointData.Length;
85 private void OnDrawGizmos()
87 DrawGizmos(_isAlwaysDraw);
89 foreach (var way
in WaypointData)
90 if (Selection.Contains(way.gameObject))
94 private void OnDrawGizmosSelected()
103 #region PUBLIC_METHODS
107 var p1 = GetRoutePosition(dist);
108 var p2 = GetRoutePosition(dist + 0.1f);
115 #region PRIVATE_METHODS
117 private Vector3 GetRoutePosition(
float dist)
120 dist = Mathf.Repeat(dist, _length);
122 while (_distances[point] < dist) ++point;
124 _p1N = (point - 1 + _numPoints) % _numPoints;
127 _i = Mathf.InverseLerp(_distances[_p1N], _distances[_p2N], dist);
131 _p0N = (point - 2 + _numPoints) % _numPoints;
132 _p3N = (point + 1) % _numPoints;
134 _p2N = _p2N % _numPoints;
141 return CatMullRom(_p0, _p1, _p2, _p3, _i);
144 _p1N = (point - 1 + _numPoints) % _numPoints;
147 return Vector3.Lerp(_points[_p1N], _points[_p2N], _i);
150 private static Vector3 CatMullRom(Vector3 p0, Vector3 p1, Vector3 p2, Vector3 p3,
float i)
153 (2 * p1 + (-p0 + p2) * i + (2 * p0 - 5 * p1 + 4 * p2 - p3) * i * i +
154 (-p0 + 3 * p1 - 3 * p2 + p3) * i * i * i);
157 private void CachePositionsAndDistances()
159 _points =
new Vector3[WaypointData.Length + 1];
160 _distances =
new float[WaypointData.Length + 1];
162 float accumulateDistance = 0;
164 for (var i = 0; i < _points.Length; i++)
166 var t1 = WaypointData[i % WaypointData.Length];
167 var t2 = WaypointData[(i + 1) % WaypointData.Length];
169 if (t1 !=
null && t2 !=
null)
171 var p1 = t1.position;
172 var p2 = t2.position;
173 _points[i] = WaypointData[i % WaypointData.Length].position;
174 _distances[i] = accumulateDistance;
175 accumulateDistance += (p1 - p2).magnitude;
180 private void DrawGizmos(
bool selected)
182 if (!selected)
return;
186 foreach (var child
in WaypointData)
188 Gizmos.color =
Color.red;
189 Gizmos.DrawCube(child.transform.position,
new Vector3(0.5f, 0.5f, 0.5f));
192 if (WaypointData.Length > 1)
194 _numPoints = WaypointData.Length;
196 CachePositionsAndDistances();
197 _length =
Circuit ? _distances[_distances.Length - 1] : _distances[_distances.Length - 2];
214 private void CreateExternal()
216 Gizmos.color =
Color.yellow;
218 var prev = WaypointData[0].position;
219 for (
float dist = 0; dist < _length; dist += _length / _curveSmoothing)
221 var next = GetRoutePosition(dist);
222 Gizmos.DrawLine(prev, next);
229 private void CreateInternal()
231 for (var n = 0; n < WaypointData.Length; n++)
233 if (!
Circuit && n == 0)
continue;
235 var currentIndex = n;
236 var nextIndex = n + 1;
237 var prevIndex = n - 1;
239 if (n - 1 < 0) prevIndex = WaypointData.Length - 1;
241 if (n + 1 >= WaypointData.Length) nextIndex =
Circuit ? 0 : WaypointData.Length - 1;
243 var currentPoint = WaypointData[currentIndex].position;
245 _curveStartPoint =
Vector3.MoveTowards(currentPoint, WaypointData[nextIndex].position, _entryDistance);
246 _curveEndPoint =
Vector3.MoveTowards(currentPoint, WaypointData[prevIndex].position, _exitDistance);
248 var prev = _curveStartPoint;
250 for (var i = 0; i < _curveSmoothingInternal; i++)
252 var t = i / (_curveSmoothingInternal - 1.0f);
253 var position = (1.0f - t) * (1.0f - t) * _curveStartPoint + 2.0f * (1.0f - t) * t * currentPoint +
254 t * t * _curveEndPoint;
256 Gizmos.color =
Color.yellow;
257 Gizmos.DrawLine(prev, position);
265 private void CreatePlainLine()
267 Gizmos.color =
Color.blue;
269 for (var n = 0; n < WaypointData.Length; n++)
271 var currentIndex = n;
272 var nextIndex = n + 1;
274 if (nextIndex >= WaypointData.Length) nextIndex =
Circuit ? 0 : WaypointData.Length - 1;
276 var prev = WaypointData[currentIndex].position;
277 var next = WaypointData[nextIndex].position;
279 Gizmos.DrawLine(prev, next);
283 private void CreateData()
285 if (WaypointData.Length > 1)
287 _numPoints = WaypointData.Length;
288 CachePositionsAndDistances();
289 _length =
Circuit ? _distances[_distances.Length - 1] : _distances[_distances.Length - 2];
306 private List<Vector3> GetPointExternal()
308 var list =
new List<Vector3>();
310 for (
float dist = 0; dist < _length; dist += _length / _curveSmoothing)
312 var point = GetRoutePosition(dist);
319 private List<Vector3> GetPointInternal()
321 var list =
new List<Vector3>();
322 for (var n = 0; n < WaypointData.Length; n++)
324 if (!
Circuit && n == 0)
continue;
326 var currentIndex = n;
327 var nextIndex = n + 1;
328 var prevIndex = n - 1;
330 if (n - 1 < 0) prevIndex = WaypointData.Length - 1;
332 if (n + 1 >= WaypointData.Length) nextIndex =
Circuit ? 0 : WaypointData.Length - 1;
334 var currentPoint = WaypointData[currentIndex].position;
336 _curveStartPoint =
Vector3.MoveTowards(currentPoint, WaypointData[nextIndex].position, _entryDistance);
337 _curveEndPoint =
Vector3.MoveTowards(currentPoint, WaypointData[prevIndex].position, _exitDistance);
339 var buffer =
new List<Vector3>();
341 for (var i = 0; i < _curveSmoothingInternal; i++)
343 var t = i / (_curveSmoothingInternal - 1.0f);
344 var position = (1.0f - t) * (1.0f - t) * _curveStartPoint + 2.0f * (1.0f - t) * t * currentPoint +
345 t * t * _curveEndPoint;
347 buffer.Add(position);
351 list.AddRange(buffer);
357 private List<Vector3> GetPointPlain()
359 var list =
new List<Vector3>();
360 list.AddRange(WaypointData.Select(t => t.position));
WaypointList _waypointList
List< Vector3 > _curvePoints
RoutePoint GetRoutePoint(float dist)