MegaDrawSpline.cs 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240
  1. using UnityEngine;
  2. using System.Collections.Generic;
  3. public class MegaDrawSpline : MonoBehaviour
  4. {
  5. public float updatedist = 1.0f;
  6. public float smooth = 0.7f;
  7. public Material mat;
  8. public float width = 1.0f;
  9. public float height = 1.0f;
  10. public float radius = 0.1f;
  11. public bool closed = true;
  12. public MeshShapeType meshtype = MeshShapeType.Box;
  13. public float offset = 0.01f;
  14. public float tradius = 1.0f;
  15. public float meshstep = 1.0f;
  16. public float closevalue = 0.1f;
  17. public bool constantspd = true;
  18. GameObject obj;
  19. Vector3 lasthitpos;
  20. bool building = false;
  21. float travelled = 0.0f;
  22. Vector3 lastdir;
  23. MegaSpline cspline;
  24. MegaShape cshape;
  25. int splinecount = 0;
  26. void Update()
  27. {
  28. if ( building )
  29. {
  30. Ray mouseRay = Camera.main.ScreenPointToRay(Input.mousePosition);
  31. RaycastHit info;
  32. bool hit = Physics.Raycast(mouseRay, out info);
  33. if ( Input.GetMouseButtonUp(0) || hit == false )
  34. {
  35. building = false;
  36. // Finish of line and make spline
  37. if ( ValidSpline() )
  38. FinishSpline(obj, lasthitpos);
  39. else
  40. Destroy(obj);
  41. obj = null;
  42. cspline = null;
  43. cshape = null;
  44. }
  45. else
  46. {
  47. if ( hit )
  48. {
  49. Vector3 hp = info.point;
  50. hp.y += offset;
  51. float dist = Vector3.Distance(lasthitpos, hp);
  52. travelled += dist;
  53. if ( travelled > updatedist )
  54. {
  55. cspline.AddKnot(cshape.transform.worldToLocalMatrix.MultiplyPoint3x4(hp), Vector3.zero, Vector3.zero);
  56. cshape.AutoCurve();
  57. travelled -= updatedist;
  58. }
  59. else
  60. {
  61. cspline.knots[cspline.knots.Count - 1].p = cshape.transform.worldToLocalMatrix.MultiplyPoint3x4(hp);
  62. cshape.AutoCurve();
  63. if ( cspline.knots.Count == 2 )
  64. {
  65. float dist1 = cspline.KnotDistance(0, 1);
  66. if ( dist1 > 0.1f )
  67. cshape.BuildMesh();
  68. }
  69. else
  70. {
  71. if ( cspline.knots.Count > 2 )
  72. cshape.BuildMesh();
  73. }
  74. }
  75. lasthitpos = hp;
  76. }
  77. }
  78. }
  79. else
  80. {
  81. if ( Input.GetMouseButtonDown(0) )
  82. {
  83. Ray mouseRay = Camera.main.ScreenPointToRay(Input.mousePosition);
  84. RaycastHit info;
  85. bool hit = Physics.Raycast(mouseRay, out info);
  86. if ( hit )
  87. {
  88. Vector3 hp = info.point;
  89. hp.y += offset;
  90. lasthitpos = hp;
  91. travelled = 0.0f;
  92. obj = CreateSpline(hp);
  93. building = true;
  94. }
  95. }
  96. }
  97. }
  98. bool ValidSpline()
  99. {
  100. if ( cspline.knots.Count == 2 )
  101. {
  102. float dist1 = cspline.KnotDistance(0, 1);
  103. if ( dist1 <= 0.1f )
  104. return false;
  105. }
  106. return true;
  107. }
  108. public MegaSpline NewSpline(MegaShape shape)
  109. {
  110. if ( shape.splines.Count == 0 )
  111. {
  112. MegaSpline newspline = new MegaSpline();
  113. shape.splines.Add(newspline);
  114. }
  115. MegaSpline spline = shape.splines[0];
  116. spline.knots.Clear();
  117. spline.closed = false;
  118. return spline;
  119. }
  120. GameObject CreateSpline(Vector3 pos)
  121. {
  122. GameObject obj = new GameObject();
  123. obj.name = name + " - Spline " + splinecount++;
  124. obj.transform.position = transform.position;
  125. //obj.transform.parent = transform;
  126. MegaShape shape = obj.AddComponent<MegaShape>();
  127. shape.smoothness = smooth;
  128. shape.drawHandles = false;
  129. MegaSpline spline = shape.splines[0]; //NewSpline(shape);
  130. spline.knots.Clear();
  131. spline.constantSpeed = constantspd;
  132. spline.subdivs = 40;
  133. shape.splines.Add(spline);
  134. shape.cap = true;
  135. Vector3[] ps = new Vector3[2];
  136. ps[0] = obj.transform.worldToLocalMatrix.MultiplyPoint3x4(pos);
  137. ps[1] = obj.transform.worldToLocalMatrix.MultiplyPoint3x4(pos);
  138. shape.BuildSpline(0, ps, false);
  139. shape.CalcLength();
  140. shape.mat1 = mat;
  141. shape.drawTwist = true;
  142. shape.makeMesh = true;
  143. shape.meshType = meshtype;
  144. shape.boxwidth = width;
  145. shape.boxheight = height;
  146. shape.offset = -height * 0.5f;
  147. shape.tradius = tradius;
  148. shape.stepdist = meshstep; //width * 2.0f * 10.0f;
  149. shape.SetMats();
  150. spline.closed = closed;
  151. cspline = spline;
  152. cshape = shape;
  153. return obj;
  154. }
  155. void FinishSpline(GameObject obj, Vector3 p)
  156. {
  157. if ( !closed )
  158. {
  159. Vector3 lp = obj.transform.worldToLocalMatrix.MultiplyPoint3x4(p);
  160. float d = Vector3.Distance(cspline.knots[0].p, lp);
  161. if ( d < updatedist * closevalue )
  162. {
  163. cspline.closed = true;
  164. cshape.cap = false;
  165. cspline.knots.RemoveAt(cspline.knots.Count - 1);
  166. }
  167. else
  168. cshape.cap = true;
  169. }
  170. else
  171. {
  172. if ( cspline.knots.Count > 2 )
  173. {
  174. float d = cspline.KnotDistance(cspline.knots.Count - 1, cspline.knots.Count - 2);
  175. if ( d < updatedist * 0.25f )
  176. cspline.knots.RemoveAt(cspline.knots.Count - 1);
  177. }
  178. float d1 = cspline.KnotDistance(cspline.knots.Count - 1, 0);
  179. if ( d1 < updatedist * closevalue )
  180. cspline.knots.RemoveAt(cspline.knots.Count - 1);
  181. }
  182. cshape.AutoCurve();
  183. cshape.BuildMesh();
  184. }
  185. void OnDrawGizmosSelected()
  186. {
  187. if ( cshape && cspline != null )
  188. {
  189. Gizmos.color = Color.white;
  190. Gizmos.matrix = obj.transform.localToWorldMatrix;
  191. for ( int i = 1; i < cspline.knots.Count; i++ )
  192. Gizmos.DrawLine(cspline.knots[i - 1].p, cspline.knots[i].p);
  193. Gizmos.color = Color.green;
  194. for ( int i = 0; i < cspline.knots.Count; i++ )
  195. Gizmos.DrawSphere(cspline.knots[i].p, radius);
  196. }
  197. }
  198. }