using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
namespace SplineMesh {
///
/// Special component to extrude shape along a spline.
///
/// Note : This component is not lightweight and should be used as-is mostly for prototyping. It allows to quickly create meshes by
/// 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
/// create eventualy the mesh you need in a modeling tool to save performances and have better control.
///
/// 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
/// for the whole spline, by setting the number of times the texture must be repeated.
///
/// 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.
///
/// You can expand the vertices list in the inspector to access data and enter precise values.
///
/// 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.
///
[ExecuteInEditMode]
[RequireComponent(typeof(Spline))]
public class SplineExtrusion : MonoBehaviour {
private Spline spline;
private bool toUpdate = true;
private GameObject generated;
public List shapeVertices = new List();
public Material material;
public float textureScale = 1;
public float sampleSpacing = 0.1f;
///
/// Clear shape vertices, then create three vertices with three normals for the extrusion to be visible
///
private void Reset() {
shapeVertices.Clear();
shapeVertices.Add(new ExtrusionSegment.Vertex(new Vector2(0, 0.5f), new Vector2(0, 1), 0));
shapeVertices.Add(new ExtrusionSegment.Vertex(new Vector2(1, -0.5f), new Vector2(1, -1), 0.33f));
shapeVertices.Add(new ExtrusionSegment.Vertex(new Vector2(-1, -0.5f), new Vector2(-1, -1), 0.66f));
toUpdate = true;
OnEnable();
}
private void OnValidate() {
toUpdate = true;
}
private void OnEnable() {
string generatedName = "generated by " + GetType().Name;
var generatedTranform = transform.Find(generatedName);
generated = generatedTranform != null ? generatedTranform.gameObject : UOUtility.Create(generatedName, gameObject);
spline = GetComponentInParent();
spline.NodeListChanged += (s, e) => toUpdate = true;
}
private void Update() {
if (toUpdate) {
GenerateMesh();
toUpdate = false;
}
}
private void GenerateMesh() {
UOUtility.DestroyChildren(generated);
int i = 0;
float textureOffset = 0.0f;
foreach (CubicBezierCurve curve in spline.GetCurves()) {
GameObject go = UOUtility.Create("segment " + i++,
generated,
typeof(MeshFilter),
typeof(MeshRenderer),
typeof(ExtrusionSegment),
typeof(MeshCollider));
go.GetComponent().material = material;
ExtrusionSegment seg = go.GetComponent();
seg.ShapeVertices = shapeVertices;
seg.TextureScale = textureScale;
seg.TextureOffset = textureOffset;
seg.SampleSpacing = sampleSpacing;
seg.SetInterval(curve);
textureOffset += curve.Length;
}
}
public void SetToUpdate() {
toUpdate = true;
}
}
}