MegaShapeRBodyPathNew.cs 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174
  1. using UnityEngine;
  2. [RequireComponent(typeof(Rigidbody))]
  3. public class MegaShapeRBodyPathNew : MonoBehaviour
  4. {
  5. public MegaShape path; // The Shape that will attract the rigid body
  6. public int curve = 0; // The sub curve of that shape usually 0
  7. public bool usealpha = false; // Set to true to use alpha value instead of finding the nearest point on the curve.
  8. public float impulse = 10.0f; // The force that will applied if the rbody is 1 unit away from the curve
  9. public float inputfrc = 10.0f; // Max forcce for user input
  10. public bool align = true; // Should rigid body align to the spline direction
  11. public float alpha = 0.0f; // current position on spline, The alpha value to use is usealpha mode set, allows you to set the point on the curve to attract the rbody (0 - 1)
  12. public float delay = 1.0f; // how quickly user input gets to max force
  13. public float drag = 0.0f; // slows object down when moving
  14. public float jump = 10.0f; // Jump force to apply when space is pressed
  15. public float breakforce = 100.0f; // force above which the rigidbody will break free from the path
  16. public bool connected = true; // Controls whether the object is connected to spline or not
  17. Rigidbody rb;
  18. float drive = 0.0f;
  19. float vel = 0.0f;
  20. float tfrc = 0.0f;
  21. Vector3 nps;
  22. void Start()
  23. {
  24. rb = GetComponent<Rigidbody>();
  25. for ( int i = 0; i < 4; i++ )
  26. Position();
  27. }
  28. void Update()
  29. {
  30. tfrc = 0.0f;
  31. if ( Input.GetKey(KeyCode.UpArrow) )
  32. tfrc = -inputfrc;
  33. else
  34. {
  35. if ( Input.GetKey(KeyCode.DownArrow) )
  36. tfrc = inputfrc;
  37. }
  38. if ( Input.GetKeyDown(KeyCode.Space) )
  39. rb.AddForce(Vector3.up * jump);
  40. drive = Mathf.SmoothDamp(drive, tfrc, ref vel, delay);
  41. Debug.DrawLine(transform.position, nps);
  42. }
  43. // Position object on spline
  44. public void Position()
  45. {
  46. if ( path && rb && connected )
  47. {
  48. Vector3 p = rb.position; //transform.position;
  49. Vector3 tangent = Vector3.zero;
  50. int kn = 0;
  51. Vector3 np = Vector3.zero;
  52. if ( usealpha )
  53. np = path.transform.TransformPoint(path.InterpCurve3D(curve, alpha, true));
  54. else
  55. np = path.FindNearestPointWorldXZ(p, 15, ref kn, ref tangent, ref alpha);
  56. nps = np;
  57. np.y = p.y;
  58. Vector3 dir = np - p;
  59. dir.y = 0.0f;
  60. Vector3 iforce = dir * impulse;
  61. rb.AddForce(iforce, ForceMode.Impulse);
  62. np.y = p.y;
  63. rb.MovePosition(np);
  64. transform.position = np;
  65. Vector3 p1 = path.transform.TransformPoint(path.InterpCurve3D(curve, alpha + 0.0001f, true));
  66. p1.y = p.y;
  67. if ( align )
  68. {
  69. Vector3 ndir = (p1 - np).normalized;
  70. Vector3 rdir = transform.forward;
  71. rdir.y = 0.0f;
  72. rdir = rdir.normalized;
  73. float angle = Vector3.Angle(rdir, ndir);
  74. Vector3 cross = Vector3.Cross(rdir, ndir);
  75. if ( cross.y < 0.0f )
  76. angle = -angle;
  77. Quaternion qrot = rb.rotation;
  78. Quaternion yrot = Quaternion.Euler(new Vector3(0.0f, angle, 0.0f)); //LookRotation(p1 - np); //.eulerAngles;
  79. rb.MoveRotation(qrot * yrot);
  80. }
  81. }
  82. }
  83. void FixedUpdate()
  84. {
  85. if ( path && rb && connected )
  86. {
  87. Vector3 p = rb.position; //transform.position;
  88. Vector3 tangent = Vector3.zero;
  89. int kn = 0;
  90. Vector3 np = Vector3.zero;
  91. if ( usealpha )
  92. np = path.transform.TransformPoint(path.InterpCurve3D(curve, alpha, true));
  93. else
  94. np = path.FindNearestPointWorldXZ(p, 15, ref kn, ref tangent, ref alpha);
  95. nps = np;
  96. np.y = p.y;
  97. Vector3 dir = np - p;
  98. dir.y = 0.0f;
  99. Vector3 iforce = dir * impulse;
  100. float mag = iforce.magnitude / Time.fixedDeltaTime;
  101. if ( mag > breakforce )
  102. {
  103. connected = false;
  104. rb.angularVelocity = Vector3.zero;
  105. }
  106. if ( connected )
  107. {
  108. rb.AddForce(iforce, ForceMode.Impulse);
  109. np.y = p.y;
  110. rb.MovePosition(np);
  111. Vector3 p1 = path.transform.TransformPoint(path.InterpCurve3D(curve, alpha + 0.0001f, true));
  112. p1.y = p.y;
  113. if ( align )
  114. {
  115. Vector3 ndir = (p1 - np).normalized;
  116. Vector3 rdir = transform.forward;
  117. rdir.y = 0.0f;
  118. rdir = rdir.normalized;
  119. float angle = Vector3.Angle(rdir, ndir);
  120. Vector3 cross = Vector3.Cross(rdir, ndir);
  121. if ( cross.y < 0.0f )
  122. angle = -angle;
  123. Quaternion qrot = rb.rotation;
  124. Quaternion yrot = Quaternion.Euler(new Vector3(0.0f, angle, 0.0f)); //LookRotation(p1 - np); //.eulerAngles;
  125. rb.MoveRotation(qrot * yrot);
  126. }
  127. if ( drag != 0.0f )
  128. rb.AddForce(-rb.velocity * drag);
  129. if ( drive != 0.0f )
  130. rb.AddForce((np - p1).normalized * drive, ForceMode.Force);
  131. }
  132. }
  133. }
  134. }