RoboticArms/Library/PackageCache/com.unity.splines@d3e1e500c9a0/Samples~/Runtime/SplineRenderer.cs
2025-11-17 15:16:36 +07:00

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);
}
}
}
}