BezierMover.cs 2.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273
  1. using UnityEngine;
  2. namespace Pathfinding.Examples {
  3. /// <summary>
  4. /// Moves an object along a spline.
  5. /// Helper script in the example scene called 'Moving'.
  6. /// </summary>
  7. [HelpURL("http://arongranberg.com/astar/documentation/stable/class_pathfinding_1_1_examples_1_1_bezier_mover.php")]
  8. public class BezierMover : MonoBehaviour {
  9. public Transform[] points;
  10. public float speed = 1;
  11. public float tiltAmount = 1f;
  12. float time = 0;
  13. Vector3 Position (float t) {
  14. int c = points.Length;
  15. int pt = Mathf.FloorToInt(t) % c;
  16. return AstarSplines.CatmullRom(points[(pt-1+c)%c].position, points[pt].position, points[(pt+1)%c].position, points[(pt+2)%c].position, t - Mathf.FloorToInt(t));
  17. }
  18. /// <summary>Update is called once per frame</summary>
  19. void Update () {
  20. float mn = time;
  21. float mx = time+1;
  22. while (mx - mn > 0.0001f) {
  23. float mid = (mn+mx)/2;
  24. Vector3 p = Position(mid);
  25. if ((p-transform.position).sqrMagnitude > (speed*Time.deltaTime)*(speed*Time.deltaTime)) {
  26. mx = mid;
  27. } else {
  28. mn = mid;
  29. }
  30. }
  31. time = (mn+mx)/2;
  32. const float dt = 0.001f;
  33. const float dt2 = 0.15f;
  34. Vector3 p1 = Position(time);
  35. Vector3 p2 = Position(time+dt);
  36. transform.position = p1;
  37. Vector3 p3 = Position(time+dt2);
  38. Vector3 p4 = Position(time+dt2 + dt);
  39. // Estimate the acceleration at the current point and use it to tilt the object inwards on the curve
  40. var acceleration = ((p4 - p3).normalized - (p2 - p1).normalized) / (p3 - p1).magnitude;
  41. var up = new Vector3(0, 1/(tiltAmount + 0.00001f), 0) + acceleration;
  42. transform.rotation = Quaternion.LookRotation(p2 - p1, up);
  43. }
  44. void OnDrawGizmos () {
  45. if (points.Length >= 3) {
  46. for (int i = 0; i < points.Length; i++) if (points[i] == null) return;
  47. Gizmos.color = Color.white;
  48. Vector3 pp = Position(0);
  49. for (int pt = 0; pt < points.Length; pt++) {
  50. for (int i = 1; i <= 100; i++) {
  51. var p = Position(pt + (i / 100f));
  52. Gizmos.DrawLine(pp, p);
  53. pp = p;
  54. }
  55. }
  56. }
  57. }
  58. }
  59. }