CheckPointsMainCS.cs 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298
  1. /*
  2. * FUNCTION:
  3. * - This script keeps a record of the CPs of active patches.
  4. * - This script translates the player position (controlled by ControllerScript.js)
  5. * on the spline into Vector3 cooridiantes.
  6. * - It calculates the angle of player and obstacles according to the spline.
  7. * - It supports the ElementsGenerator.js to generate obstacles on the path also by
  8. * translating position on spline to Vector3 coordinates.
  9. *
  10. * USED BY:
  11. * This script is a part of the "Player" prefab.
  12. *
  13. * INFO: Understanding of algorithms that make the calculation based on spline is not
  14. * necessary. A high level undertstanding of each function can however can be handy.
  15. *
  16. */
  17. using UnityEngine;
  18. using System.Collections;
  19. public class CheckPointsMainCS : MonoBehaviour {
  20. //Constants
  21. private float defaultPathLength = 3048.0f;
  22. public float getDefaultPathLength() { return defaultPathLength; }
  23. //Variables
  24. public static float fPathLength = 0.0f;//length displacement of current patch
  25. public static float fNextPathLength = 0.0f;//length displacement of next patch
  26. public float CurrentAngle = 0.0f;
  27. public Vector3 CurrentDir;
  28. public Vector2 Current_MidPoint;
  29. public Vector3[] CPPositions;
  30. private Vector3[] NextCPPositions;
  31. private float WaypointAngle = 0.0f;
  32. public float CurrentPercent = 0.0f;
  33. private GameObject goCPsGroup;
  34. private GameObject goNextCPsGroup;
  35. private Transform tCPsGroup;
  36. private Transform tNextCPsGroup;
  37. //script references
  38. private InGameScriptCS hInGameScriptCS;
  39. private ControllerScriptCS hControllerScriptCS;
  40. private PatchesRandomizerCS hPatchesRandomizerCS;
  41. private ElementsGeneratorCS hElementsGeneratorCS;
  42. public int PatchNumber = 0;
  43. void Start()
  44. {
  45. WaypointAngle = 0.0f;
  46. fPathLength = defaultPathLength;
  47. fNextPathLength = defaultPathLength;
  48. CurrentPercent = 0.0f;
  49. hInGameScriptCS = (InGameScriptCS)this.GetComponent(typeof(InGameScriptCS));
  50. hControllerScriptCS = (ControllerScriptCS)this.GetComponent(typeof(ControllerScriptCS));
  51. hPatchesRandomizerCS = (PatchesRandomizerCS)this.GetComponent(typeof(PatchesRandomizerCS));
  52. hElementsGeneratorCS = (ElementsGeneratorCS)this.GetComponent(typeof(ElementsGeneratorCS));
  53. }
  54. /*
  55. * FUNCTION: Get the CP gameobjects of the currently active patches.
  56. * USED BY: PatchesRandomizer.Start()
  57. * PatchesRandomizer.Start()
  58. */
  59. public void setChildGroups()
  60. {
  61. foreach (Transform child in hPatchesRandomizerCS.getCurrentPatch().transform)
  62. {
  63. if(child.name.Contains("CheckPoints"))
  64. goCPsGroup = child.gameObject;
  65. }
  66. foreach (Transform child in hPatchesRandomizerCS.getNextPatch().transform)
  67. {
  68. if(child.name.Contains("CheckPoints"))
  69. goNextCPsGroup = child.gameObject;
  70. }
  71. }
  72. /*
  73. * FUNCTION: Get the CP transforms of the currently active patch and store them in array.
  74. * USED BY: PatchesRandomizer.Start()
  75. */
  76. public void SetCurrentPatchCPs()
  77. {
  78. CurrentAngle = 90.0f;
  79. tCPsGroup = goCPsGroup.transform;
  80. fPathLength = ((PathLineDrawerCS)tCPsGroup.GetComponent(typeof(PathLineDrawerCS))).fPathLength;
  81. CPPositions = new Vector3[((PathLineDrawerCS)tCPsGroup.GetComponent(typeof(PathLineDrawerCS))).Parameterized_CPPositions.Length];
  82. for(int i=0;i<CPPositions.Length;i++)
  83. {
  84. CPPositions[i] = ((PathLineDrawerCS)tCPsGroup.GetComponent(typeof(PathLineDrawerCS))).Parameterized_CPPositions[i];
  85. CPPositions[i].x = CPPositions[i].x + PatchNumber * defaultPathLength;
  86. }
  87. PatchNumber++;
  88. }
  89. /*
  90. * FUNCTION: Get the CP transforms of the next active patch and store them in array.
  91. * USED BY: PatchesRandomizer.Start()
  92. */
  93. public void SetNextPatchCPs()
  94. {
  95. tNextCPsGroup = goNextCPsGroup.transform;
  96. fNextPathLength = ((PathLineDrawerCS)tNextCPsGroup.GetComponent(typeof(PathLineDrawerCS))).fPathLength;
  97. NextCPPositions = new Vector3[((PathLineDrawerCS)tNextCPsGroup.GetComponent(typeof(PathLineDrawerCS))).Parameterized_CPPositions.Length];
  98. for(int i=0;i<NextCPPositions.Length;i++)
  99. {
  100. NextCPPositions[i] = ( (PathLineDrawerCS)tNextCPsGroup.GetComponent(typeof(PathLineDrawerCS)) ).Parameterized_CPPositions[i];
  101. NextCPPositions[i].x = NextCPPositions[i].x + PatchNumber * defaultPathLength;
  102. }
  103. }
  104. /*
  105. * FUNCTION: Gets the vector position from the location on the spline.
  106. *
  107. * PARAMETER 1: The array of CPs of the patch.
  108. * PATAMETER 2: Location on spline.
  109. */
  110. //andeeee from the Unity forum's steller Catmull-Rom class ( http://forum.unity3d.com/viewtopic.php?p=218400#218400 ):
  111. private Vector3 Interp(Vector3[] pts , float t)
  112. {
  113. t = Mathf.Clamp(t,0.0f,2.0f);
  114. int numSections = pts.Length - 3;
  115. int currPt = Mathf.Min(Mathf.FloorToInt(t * numSections), numSections - 1);
  116. float u = t * numSections - currPt;
  117. Vector3 a = pts[currPt];
  118. Vector3 b = pts[currPt + 1];
  119. Vector3 c = pts[currPt + 2];
  120. Vector3 d = pts[currPt + 3];
  121. return .5f * (
  122. (-a + 3f * b - 3f * c + d) * (u * u * u)
  123. + (2f * a - 5f * b + 4f * c - d) * (u * u)
  124. + (-a + c) * u
  125. + 2f * b
  126. );
  127. }
  128. /*
  129. * FUNCTION: Set distance on patch based on the spline.
  130. * CALLED BY: ControllerScript.SetTransform()
  131. */
  132. public float SetNextMidPointandRotation(float CurrentDistanceOnPath, float CurrentForwardSpeed)
  133. {
  134. CurrentPercent = (CurrentDistanceOnPath+CurrentForwardSpeed)/fPathLength;
  135. if(CurrentPercent>=1.0)//if the Player has crossed the current patch
  136. {
  137. float PreviousPathLength = fPathLength;
  138. ((PatchesRandomizerCS)GameObject.Find("Player").GetComponent(typeof(PatchesRandomizerCS) )).createNewPatch();
  139. CurrentDistanceOnPath = (CurrentDistanceOnPath+CurrentForwardSpeed) - PreviousPathLength;
  140. CurrentDistanceOnPath = Mathf.Abs(CurrentDistanceOnPath);
  141. hControllerScriptCS.setCurrentDistanceOnPath(CurrentDistanceOnPath);
  142. SetCurrentPatchCPs();
  143. SetNextPatchCPs();
  144. CurrentPercent = (CurrentDistanceOnPath+CurrentForwardSpeed)/fPathLength;
  145. }
  146. Vector3 MidPointVector3 = Interp(CPPositions,CurrentPercent);
  147. Current_MidPoint.x = MidPointVector3.x;
  148. Current_MidPoint.y = MidPointVector3.z;
  149. Vector3 ForwardPointVector3 = Interp(CPPositions,CurrentPercent+0.001f);
  150. Vector3 BackPointVector3 = Interp(CPPositions,CurrentPercent-0.001f);
  151. CurrentDir = ForwardPointVector3 - BackPointVector3;
  152. CurrentAngle = PosAngleofVector(CurrentDir);
  153. if(CurrentAngle>180.0f)
  154. CurrentAngle = CurrentAngle-360.0f;
  155. return (CurrentDistanceOnPath+CurrentForwardSpeed);
  156. }
  157. /*
  158. * FUNCTION: Calculate the rotation along y-axis based on the position.
  159. * USED BY: SetNextMidPointandRotation(...)
  160. * SetNextMidPointandRotation(...)
  161. * getCurrentWSPointBasedOnPercent(...)
  162. * getNextWSPointBasedOnPercent(...)
  163. *
  164. */
  165. private float PosAngleofVector(Vector3 InputVector)
  166. {
  167. float AngleofInputVector = 57.3f * (Mathf.Atan2(InputVector.z,InputVector.x));
  168. if(AngleofInputVector<0.0f)
  169. AngleofInputVector = AngleofInputVector + 360.0f;
  170. return AngleofInputVector;
  171. }
  172. /*
  173. * FUNCTION: The angle the spline makes on the percentile position on current patch.
  174. * USED BY: ControllerScript.SetTransform()
  175. * INFO: The CurrentAngle is calculated byte the SetNextMidPointandRotation(...) and
  176. * returned to the ControllerScript using this getter function in each frame.
  177. */
  178. public float getCurrentAngle()
  179. {
  180. return CurrentAngle;
  181. }
  182. /*
  183. * FUNCTION: Get the Vector3 position based on area covered on spline of current patch.
  184. * USED BY: ElementsGenerator.getPosition(...)
  185. * INFO: The spline is assumed to be 1. The starting point is 0.0 and
  186. * the end point is 1.0. Any value between 0 and 1 is the percentile position on
  187. * the spline.
  188. */
  189. public Vector3 getCurrentWSPointBasedOnPercent(float Percent_Val)
  190. {
  191. Vector3 NextSideDir = new Vector3(0,0,1);
  192. Vector3 ForwardPointVector3 = Interp(CPPositions,(Percent_Val+0.001f));
  193. Vector3 BackPointVector3 = Interp(CPPositions,(Percent_Val-0.001f));
  194. Vector3 NextCurrentDir = ForwardPointVector3 - BackPointVector3;
  195. NextSideDir = RotateY0Vector(NextCurrentDir, 90.0f);
  196. NextSideDir.Normalize();
  197. WaypointAngle = PosAngleofVector(NextCurrentDir);
  198. if(WaypointAngle>180.0f)
  199. WaypointAngle = WaypointAngle-360.0f;
  200. return Interp(CPPositions,Percent_Val);
  201. }
  202. /*
  203. * FUNCTION: Get the Vector3 position based on area covered on spline of next patch.
  204. * USED BY: ElementsGenerator.getPosition(...)
  205. * INFO: The spline is assumed to be 1. The starting point is 0.0 and
  206. * the end point is 1.0. Any value between 0 and 1 is the percentile position on
  207. * the spline.
  208. */
  209. public Vector3 getNextWSPointBasedOnPercent(float Percent_Val)
  210. {
  211. Vector3 NextSideDir = new Vector3(0,0,1);
  212. Vector3 ForwardPointVector3 = Interp(NextCPPositions,(Percent_Val+0.001f));
  213. Vector3 BackPointVector3 = Interp(NextCPPositions,(Percent_Val-0.001f));
  214. Vector3 NextCurrentDir = ForwardPointVector3 - BackPointVector3;
  215. NextSideDir = RotateY0Vector(NextCurrentDir, 90.0f);
  216. NextSideDir.Normalize();
  217. WaypointAngle = PosAngleofVector(NextCurrentDir);
  218. if(WaypointAngle>180.0f)
  219. WaypointAngle = WaypointAngle-360.0f;
  220. return Interp(NextCPPositions,Percent_Val);
  221. }
  222. /*
  223. * FUNCTION: The angle the spline makes on the percentile position on current patch.
  224. * USED BY: ElementsGenerator.generateElements(...)
  225. * INFO: The WaypointAngle is calculated int the getNextWSPointBasedOnPercent(...)
  226. * function and used by ElementsGenerator whenever an element is placed on the path.
  227. */
  228. public float getWaypointAngle()
  229. {
  230. return WaypointAngle;
  231. }
  232. /*
  233. * FUNCTION: Get the current direction of the player on the spline.
  234. * USED BY: ControllerScript.SetTransform()
  235. */
  236. public Vector3 getCurrentDirection() { return CurrentDir; }
  237. /*
  238. * FUNCTION: Get the exact position under the spline.
  239. * USED BY: ControllerScript.calculateHorizontalPosition(...)
  240. * INFO: This is used to position the player character in one of the three lanes.
  241. */
  242. public Vector2 getCurrentMidPoint() { return Current_MidPoint; }
  243. /*
  244. * FUNCTION: Calculate the needed rotation based on spline direction.
  245. * USED BY: getCurrentWSPointBasedOnPercent(...)
  246. * getNextWSPointBasedOnPercent(...)
  247. */
  248. private Vector3 RotateY0Vector(Vector3 inputVector, float angletoRotate)
  249. {
  250. Vector3 FinalVector = Vector3.zero;
  251. angletoRotate = angletoRotate/57.3f;
  252. FinalVector.x = Mathf.Cos(angletoRotate) * inputVector.x - Mathf.Sin(angletoRotate) * inputVector.z;
  253. FinalVector.z = Mathf.Sin(angletoRotate) * inputVector.x + Mathf.Cos(angletoRotate) * inputVector.z;
  254. return FinalVector;
  255. }
  256. }