110 lines
3.4 KiB
C#
110 lines
3.4 KiB
C#
using System;
|
|
using System.Linq;
|
|
using Unity.Mathematics;
|
|
using UnityEngine;
|
|
using UnityEngine.Splines;
|
|
|
|
namespace Unity.Splines.Examples
|
|
{
|
|
[Serializable]
|
|
public struct SplineLineRendererSettings
|
|
{
|
|
public float width;
|
|
public Material material;
|
|
[Range(16, 512)]
|
|
public int subdivisions;
|
|
public Color startColor, endColor;
|
|
}
|
|
|
|
[RequireComponent(typeof(SplineContainer))]
|
|
public class SplineRenderer : MonoBehaviour
|
|
{
|
|
SplineContainer m_SplineContainer;
|
|
Spline[] m_Splines;
|
|
bool m_Dirty;
|
|
Vector3[] m_Points;
|
|
|
|
[SerializeField]
|
|
SplineLineRendererSettings m_LineRendererSettings = new SplineLineRendererSettings() {
|
|
width = .5f,
|
|
subdivisions = 64
|
|
};
|
|
|
|
LineRenderer[] m_Lines;
|
|
|
|
void Awake()
|
|
{
|
|
m_SplineContainer = GetComponent<SplineContainer>();
|
|
m_Splines = m_SplineContainer.Splines.ToArray();
|
|
}
|
|
|
|
void OnEnable()
|
|
{
|
|
Spline.Changed += OnSplineChanged;
|
|
}
|
|
|
|
void OnDisable()
|
|
{
|
|
Spline.Changed -= OnSplineChanged;
|
|
}
|
|
|
|
void OnSplineChanged(Spline spline, int knotIndex, SplineModification modificationType)
|
|
{
|
|
for (int i = 0, c = m_Splines.Length; !m_Dirty && i < c; ++i)
|
|
if (m_Splines[i] == spline)
|
|
m_Dirty = true;
|
|
}
|
|
|
|
void Update()
|
|
{
|
|
if (m_Lines?.Length != m_Splines.Length)
|
|
{
|
|
if (m_Lines != null)
|
|
foreach (var line in m_Lines) DestroyImmediate(line.gameObject);
|
|
|
|
m_Lines = new LineRenderer[m_Splines.Length];
|
|
|
|
for (int i = 0, c = m_Splines.Length; i < c; ++i)
|
|
{
|
|
m_Lines[i] = new GameObject().AddComponent<LineRenderer>();
|
|
m_Lines[i].gameObject.name = $"SplineRenderer {i}";
|
|
m_Lines[i].transform.SetParent(transform, true);
|
|
}
|
|
|
|
m_Dirty = true;
|
|
}
|
|
|
|
// It's nice to be able to see resolution changes at runtime
|
|
if (m_Points?.Length != m_LineRendererSettings.subdivisions)
|
|
{
|
|
m_Dirty = true;
|
|
m_Points = new Vector3[m_LineRendererSettings.subdivisions];
|
|
foreach (var line in m_Lines)
|
|
line.positionCount = m_LineRendererSettings.subdivisions;
|
|
}
|
|
|
|
if (!m_Dirty)
|
|
return;
|
|
|
|
m_Dirty = false;
|
|
var trs = m_SplineContainer.transform.localToWorldMatrix;
|
|
|
|
for (int s = 0, c = m_Splines.Length; s < c; ++s)
|
|
{
|
|
if (m_Splines[s].Count < 1)
|
|
continue;
|
|
|
|
for (int i = 0; i < m_LineRendererSettings.subdivisions; i++)
|
|
m_Points[i] = math.transform(trs, m_Splines[s].EvaluatePosition(i / (m_LineRendererSettings.subdivisions - 1f)));
|
|
|
|
m_Lines[s].widthCurve = new AnimationCurve(new Keyframe(0f, m_LineRendererSettings.width));
|
|
m_Lines[s].startColor = m_LineRendererSettings.startColor;
|
|
m_Lines[s].endColor = m_LineRendererSettings.endColor;
|
|
m_Lines[s].material = m_LineRendererSettings.material;
|
|
m_Lines[s].useWorldSpace = true;
|
|
m_Lines[s].SetPositions(m_Points);
|
|
}
|
|
}
|
|
}
|
|
}
|