SplineExtrusion.cs 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  1. using System;
  2. using System.Collections;
  3. using System.Collections.Generic;
  4. using System.Linq;
  5. using UnityEngine;
  6. namespace SplineMesh {
  7. /// <summary>
  8. /// Special component to extrude shape along a spline.
  9. ///
  10. /// Note : This component is not lightweight and should be used as-is mostly for prototyping. It allows to quickly create meshes by
  11. /// drawing only the 2D shape to extrude along the spline. The result is not intended to be used in a production context and you will most likely
  12. /// create eventualy the mesh you need in a modeling tool to save performances and have better control.
  13. ///
  14. /// The special editor of this component allow you to draw a 2D shape with vertices, normals and U texture coordinate. The V coordinate is set
  15. /// for the whole spline, by setting the number of times the texture must be repeated.
  16. ///
  17. /// All faces of the resulting mesh are smoothed. If you want to obtain an edge without smoothing, you will have to overlap two vertices and set two normals.
  18. ///
  19. /// You can expand the vertices list in the inspector to access data and enter precise values.
  20. ///
  21. /// This component doesn't offer much control as Unity is not a modeling tool. That said, you should be able to create your own version easily.
  22. /// </summary>
  23. [ExecuteInEditMode]
  24. [RequireComponent(typeof(Spline))]
  25. public class SplineExtrusion : MonoBehaviour {
  26. private Spline spline;
  27. private bool toUpdate = true;
  28. private GameObject generated;
  29. public List<ExtrusionSegment.Vertex> shapeVertices = new List<ExtrusionSegment.Vertex>();
  30. public Material material;
  31. public float textureScale = 1;
  32. public float sampleSpacing = 0.1f;
  33. /// <summary>
  34. /// Clear shape vertices, then create three vertices with three normals for the extrusion to be visible
  35. /// </summary>
  36. private void Reset() {
  37. shapeVertices.Clear();
  38. shapeVertices.Add(new ExtrusionSegment.Vertex(new Vector2(0, 0.5f), new Vector2(0, 1), 0));
  39. shapeVertices.Add(new ExtrusionSegment.Vertex(new Vector2(1, -0.5f), new Vector2(1, -1), 0.33f));
  40. shapeVertices.Add(new ExtrusionSegment.Vertex(new Vector2(-1, -0.5f), new Vector2(-1, -1), 0.66f));
  41. toUpdate = true;
  42. OnEnable();
  43. }
  44. private void OnValidate() {
  45. toUpdate = true;
  46. }
  47. private void OnEnable() {
  48. string generatedName = "generated by " + GetType().Name;
  49. var generatedTranform = transform.Find(generatedName);
  50. generated = generatedTranform != null ? generatedTranform.gameObject : UOUtility.Create(generatedName, gameObject);
  51. spline = GetComponentInParent<Spline>();
  52. spline.NodeListChanged += (s, e) => toUpdate = true;
  53. }
  54. private void Update() {
  55. if (toUpdate) {
  56. GenerateMesh();
  57. toUpdate = false;
  58. }
  59. }
  60. private void GenerateMesh() {
  61. UOUtility.DestroyChildren(generated);
  62. int i = 0;
  63. float textureOffset = 0.0f;
  64. foreach (CubicBezierCurve curve in spline.GetCurves()) {
  65. GameObject go = UOUtility.Create("segment " + i++,
  66. generated,
  67. typeof(MeshFilter),
  68. typeof(MeshRenderer),
  69. typeof(ExtrusionSegment),
  70. typeof(MeshCollider));
  71. go.GetComponent<MeshRenderer>().material = material;
  72. ExtrusionSegment seg = go.GetComponent<ExtrusionSegment>();
  73. seg.ShapeVertices = shapeVertices;
  74. seg.TextureScale = textureScale;
  75. seg.TextureOffset = textureOffset;
  76. seg.SampleSpacing = sampleSpacing;
  77. seg.SetInterval(curve);
  78. textureOffset += curve.Length;
  79. }
  80. }
  81. public void SetToUpdate() {
  82. toUpdate = true;
  83. }
  84. }
  85. }