MegaTracks.cs 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281
  1. using UnityEngine;
  2. [ExecuteInEditMode]
  3. [AddComponentMenu("MegaShapes/Track")]
  4. public class MegaTracks : MonoBehaviour
  5. {
  6. public MegaShape shape;
  7. public int curve = 0;
  8. public float start = 0.0f;
  9. public Vector3 rotate = Vector3.zero;
  10. public bool displayspline = true;
  11. public Vector3 linkOff = Vector3.zero;
  12. public Vector3 linkScale = Vector3.one;
  13. public Vector3 linkOff1 = new Vector3(0.0f, 1.0f, 0.0f);
  14. public Vector3 linkPivot = Vector3.zero;
  15. public Vector3 linkRot = Vector3.zero;
  16. public GameObject LinkObj;
  17. public bool RandomOrder = false;
  18. public float LinkSize = 1.0f;
  19. public bool dolateupdate = false;
  20. public bool animate = false;
  21. public float speed = 0.0f;
  22. public Vector3 trackup = Vector3.up;
  23. public bool InvisibleUpdate = false;
  24. public int seed = 0;
  25. public bool rebuild = true;
  26. bool visible = true;
  27. public bool randRot = false;
  28. float lastpos = -1.0f;
  29. Matrix4x4 tm;
  30. Matrix4x4 wtm;
  31. int linkcount = 0;
  32. int remain;
  33. Transform[] linkobjs;
  34. [ContextMenu("Help")]
  35. public void Help()
  36. {
  37. Application.OpenURL("http://www.west-racing.com/mf/?page_id=3538");
  38. }
  39. void Awake()
  40. {
  41. lastpos = -1.0f;
  42. rebuild = true;
  43. Rebuild();
  44. }
  45. void Reset()
  46. {
  47. Rebuild();
  48. }
  49. public void Rebuild()
  50. {
  51. BuildTrack();
  52. }
  53. void Update()
  54. {
  55. if ( animate )
  56. {
  57. if ( Application.isPlaying )
  58. start += speed * Time.deltaTime;
  59. }
  60. if ( visible || InvisibleUpdate )
  61. {
  62. if ( !dolateupdate )
  63. BuildTrack();
  64. }
  65. }
  66. void LateUpdate()
  67. {
  68. if ( visible || InvisibleUpdate )
  69. {
  70. if ( dolateupdate )
  71. BuildTrack();
  72. }
  73. }
  74. void BuildTrack()
  75. {
  76. if ( shape != null && LinkObj != null )
  77. {
  78. if ( rebuild || lastpos != start )
  79. {
  80. rebuild = false;
  81. lastpos = start;
  82. BuildObjectLinks(shape);
  83. }
  84. }
  85. }
  86. void OnBecameVisible()
  87. {
  88. visible = true;
  89. }
  90. void OnBecameInvisible()
  91. {
  92. visible = false;
  93. }
  94. // Taken from chain mesher
  95. void InitLinkObjects(MegaShape path)
  96. {
  97. if ( LinkObj == null )
  98. return;
  99. float len = path.splines[curve].length;
  100. // Assume z axis for now
  101. float linklen = (linkOff1.y - linkOff.y) * linkScale.x * LinkSize;
  102. linkcount = (int)(len / linklen);
  103. for ( int i = linkcount; i < gameObject.transform.childCount; i++ )
  104. {
  105. GameObject go = gameObject.transform.GetChild(i).gameObject;
  106. if ( Application.isEditor )
  107. DestroyImmediate(go);
  108. else
  109. Destroy(go);
  110. }
  111. linkobjs = new Transform[linkcount];
  112. if ( linkcount > gameObject.transform.childCount )
  113. {
  114. for ( int i = 0; i < gameObject.transform.childCount; i++ )
  115. {
  116. GameObject go = gameObject.transform.GetChild(i).gameObject;
  117. #if UNITY_3_5
  118. go.SetActiveRecursively(true);
  119. #else
  120. go.SetActive(true);
  121. #endif
  122. linkobjs[i] = go.transform;
  123. }
  124. int index = gameObject.transform.childCount;
  125. for ( int i = index; i < linkcount; i++ )
  126. {
  127. GameObject go = new GameObject();
  128. go.name = "Link";
  129. GameObject obj = LinkObj;
  130. if ( obj )
  131. {
  132. MeshRenderer mr = (MeshRenderer)obj.GetComponent<MeshRenderer>();
  133. Mesh ms = MegaUtils.GetSharedMesh(obj);
  134. MeshRenderer mr1 = (MeshRenderer)go.AddComponent<MeshRenderer>();
  135. MeshFilter mf1 = (MeshFilter)go.AddComponent<MeshFilter>();
  136. mf1.sharedMesh = ms;
  137. mr1.sharedMaterial = mr.sharedMaterial;
  138. go.transform.parent = gameObject.transform;
  139. linkobjs[i] = go.transform;
  140. }
  141. }
  142. }
  143. else
  144. {
  145. for ( int i = 0; i < linkcount; i++ )
  146. {
  147. GameObject go = gameObject.transform.GetChild(i).gameObject;
  148. #if UNITY_3_5
  149. go.SetActiveRecursively(true);
  150. #else
  151. go.SetActive(true);
  152. #endif
  153. linkobjs[i] = go.transform;
  154. }
  155. }
  156. #if UNITY_5_4 || UNITY_5_5 || UNITY_5_6 || UNITY_2017 || UNITY_2018 || UNITY_2019 || UNITY_2020
  157. Random.InitState(0);
  158. #else
  159. Random.seed = 0;
  160. #endif
  161. for ( int i = 0; i < linkcount; i++ )
  162. {
  163. GameObject obj = LinkObj; //1[oi];
  164. GameObject go = gameObject.transform.GetChild(i).gameObject;
  165. MeshRenderer mr = (MeshRenderer)obj.GetComponent<MeshRenderer>();
  166. Mesh ms = MegaUtils.GetSharedMesh(obj);
  167. MeshRenderer mr1 = (MeshRenderer)go.GetComponent<MeshRenderer>();
  168. MeshFilter mf1 = (MeshFilter)go.GetComponent<MeshFilter>();
  169. mf1.sharedMesh = ms;
  170. mr1.sharedMaterials = mr.sharedMaterials;
  171. }
  172. }
  173. void BuildObjectLinks(MegaShape path)
  174. {
  175. float len = path.splines[curve].length;
  176. if ( LinkSize < 0.1f )
  177. LinkSize = 0.1f;
  178. // Assume z axis for now
  179. float linklen = (linkOff1.y - linkOff.y) * linkScale.x * LinkSize;
  180. int lc = (int)(len / linklen);
  181. if ( lc != linkcount )
  182. InitLinkObjects(path);
  183. Quaternion linkrot1 = Quaternion.identity;
  184. linkrot1 = Quaternion.Euler(rotate);
  185. float spos = start * 0.01f;
  186. Vector3 poff = linkPivot * linkScale.x * LinkSize;
  187. float lastalpha = spos;
  188. Vector3 pos = Vector3.zero;
  189. Matrix4x4 pmat = Matrix4x4.TRS(poff, linkrot1, Vector3.one);
  190. Vector3 lrot = Vector3.zero;
  191. Quaternion frot = Quaternion.identity;
  192. #if UNITY_5_4 || UNITY_5_5 || UNITY_5_6 || UNITY_2017 || UNITY_2018 || UNITY_2019 || UNITY_2020
  193. Random.InitState(seed);
  194. #else
  195. Random.seed = seed;
  196. #endif
  197. for ( int i = 0; i < linkcount; i++ )
  198. {
  199. float alpha = ((float)(i + 1) / (float)linkcount) + spos;
  200. Quaternion lq = GetLinkQuat(alpha, lastalpha, out pos, path);
  201. lastalpha = alpha;
  202. Quaternion lr = Quaternion.Euler(lrot);
  203. frot = lq * linkrot1 * lr;
  204. if ( linkobjs[i] )
  205. {
  206. Matrix4x4 lmat = Matrix4x4.TRS(pos, lq, Vector3.one) * pmat;
  207. linkobjs[i].localPosition = lmat.GetColumn(3);
  208. linkobjs[i].localRotation = frot;
  209. linkobjs[i].localScale = linkScale * LinkSize;
  210. }
  211. if ( randRot )
  212. {
  213. float r = Random.Range(0.0f, 1.0f);
  214. lrot = (int)(r * (int)(360.0f / MegaUtils.LargestValue1(linkRot))) * linkRot;
  215. }
  216. else
  217. lrot += linkRot;
  218. }
  219. }
  220. Quaternion GetLinkQuat(float alpha, float last, out Vector3 ps, MegaShape path)
  221. {
  222. int k = 0;
  223. ps = path.splines[curve].InterpCurve3D(last, shape.normalizedInterp, ref k);
  224. Vector3 ps1 = path.splines[curve].InterpCurve3D(alpha, shape.normalizedInterp, ref k);
  225. Vector3 relativePos = ps1 - ps;
  226. Quaternion rotation = Quaternion.LookRotation(relativePos, trackup);
  227. return rotation;
  228. }
  229. }