129 lines
3.6 KiB
C#
129 lines
3.6 KiB
C#
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using UnityEngine;
|
|
|
|
namespace SplineMesh
|
|
{
|
|
[ExecuteInEditMode]
|
|
[SelectionBase]
|
|
[DisallowMultipleComponent]
|
|
public class SplineBending : MonoBehaviour
|
|
{
|
|
private GameObject generated;
|
|
|
|
private Spline spline;
|
|
|
|
private bool toUpdate;
|
|
|
|
[Tooltip("Mesh to bend along the spline.")]
|
|
public Mesh mesh;
|
|
|
|
[Tooltip("Material to apply on the bent mesh.")]
|
|
public Material material;
|
|
|
|
[Tooltip("Physic material to apply on the bent mesh.")]
|
|
public PhysicMaterial physicMaterial;
|
|
|
|
[Tooltip("Translation to apply on the mesh before bending it.")]
|
|
public Vector3 translation;
|
|
|
|
[Tooltip("Rotation to apply on the mesh before bending it.")]
|
|
public Vector3 rotation;
|
|
|
|
[Tooltip("Scale to apply on the mesh before bending it.")]
|
|
public Vector3 scale = Vector3.one;
|
|
|
|
[Tooltip("If true, a mesh collider will be generated.")]
|
|
public bool generateCollider = true;
|
|
|
|
[Tooltip("If true, the mesh will be bent on play mode. If false, the bent mesh will be kept from the editor mode, allowing lighting baking.")]
|
|
public bool updateInPlayMode;
|
|
|
|
[Tooltip("If true, a mesh will be placed on each curve of the spline. If false, a single mesh will be placed for the whole spline.")]
|
|
public bool curveSpace;
|
|
|
|
[Tooltip("The mode to use to fill the choosen interval with the bent mesh.")]
|
|
public MeshBender.FillingMode mode = MeshBender.FillingMode.StretchToInterval;
|
|
|
|
private void OnEnable()
|
|
{
|
|
string n = "generated by " + GetType().Name;
|
|
Transform transform = base.transform.Find(n);
|
|
generated = ((transform != null) ? transform.gameObject : UOUtility.Create(n, base.gameObject));
|
|
spline = GetComponentInParent<Spline>();
|
|
spline.NodeListChanged += delegate
|
|
{
|
|
toUpdate = true;
|
|
};
|
|
toUpdate = true;
|
|
}
|
|
|
|
private void OnValidate()
|
|
{
|
|
if (!(spline == null))
|
|
{
|
|
toUpdate = true;
|
|
}
|
|
}
|
|
|
|
private void Update()
|
|
{
|
|
if ((updateInPlayMode || !Application.isPlaying) && toUpdate)
|
|
{
|
|
toUpdate = false;
|
|
CreateMeshes();
|
|
}
|
|
}
|
|
|
|
public void CreateMeshes()
|
|
{
|
|
List<GameObject> list = new List<GameObject>();
|
|
if (curveSpace)
|
|
{
|
|
int num = 0;
|
|
foreach (CubicBezierCurve curf in spline.curves)
|
|
{
|
|
GameObject gameObject = FindOrCreate("segment " + num++ + " mesh");
|
|
gameObject.GetComponent<MeshBender>().SetInterval(curf);
|
|
gameObject.GetComponent<MeshCollider>().enabled = generateCollider;
|
|
list.Add(gameObject);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
GameObject gameObject2 = FindOrCreate("segment 1 mesh");
|
|
gameObject2.GetComponent<MeshBender>().SetInterval(spline, 0f);
|
|
gameObject2.GetComponent<MeshCollider>().enabled = generateCollider;
|
|
list.Add(gameObject2);
|
|
}
|
|
foreach (GameObject item in (from Transform child in generated.transform
|
|
select child.gameObject).Except(list))
|
|
{
|
|
UOUtility.Destroy(item);
|
|
}
|
|
}
|
|
|
|
private GameObject FindOrCreate(string name)
|
|
{
|
|
Transform transform = generated.transform.Find(name);
|
|
GameObject gameObject;
|
|
if (transform == null)
|
|
{
|
|
gameObject = UOUtility.Create(name, generated, typeof(MeshFilter), typeof(MeshRenderer), typeof(MeshBender), typeof(MeshCollider));
|
|
gameObject.isStatic = !updateInPlayMode;
|
|
}
|
|
else
|
|
{
|
|
gameObject = transform.gameObject;
|
|
}
|
|
gameObject.GetComponent<MeshRenderer>().material = material;
|
|
gameObject.GetComponent<MeshCollider>().material = physicMaterial;
|
|
MeshBender component = gameObject.GetComponent<MeshBender>();
|
|
component.Source = SourceMesh.Build(mesh).Translate(translation).Rotate(Quaternion.Euler(rotation))
|
|
.Scale(scale);
|
|
component.Mode = mode;
|
|
return gameObject;
|
|
}
|
|
}
|
|
}
|