using System;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Splines;
namespace Pursuit.MonoBehaviours
{
public class ParentedSpline : ContextBehaviour
{
[SerializeField] private SplineContainer splineContainer;
[SerializeField] private List<Transform> transforms;
private readonly List<BezierKnot> knots = new();
[NonSerialized] private readonly bool mode = false;
private readonly List<Vector3> positionOffsets = new();
private readonly List<Quaternion> rotationOffsets = new();
private void Awake()
{
Setup();
}
protected override void Update()
{
}
private void LateUpdate()
{
Transform splineTransform = splineContainer.transform;
Spline spline = splineContainer.Spline;
for (int index = 0; index < spline.Count; ++index)
{
BezierKnot knot = spline[index];
Transform parent = transforms[index];
Vector3 positionOffset = parent.TransformPoint(positionOffsets[index]);
knot.Position = splineTransform.InverseTransformPoint(positionOffset);
knot.Rotation = Quaternion.Inverse(splineTransform.rotation) * parent.transform.rotation *
rotationOffsets[index];
knots[index] = knot;
if (mode)
spline.SetKnot(index, knot);
}
if (!mode)
spline.SetKnots(knots);
}
[ContextMenu("Recalculate")]
private void Setup()
{
Transform splineTransform = splineContainer.transform;
Spline spline = splineContainer.Spline;
knots.Clear();
positionOffsets.Clear();
rotationOffsets.Clear();
knots.AddRange(spline.Knots);
for (int index = 0; index < spline.Count; ++index)
{
BezierKnot knot = knots[index];
Transform parent = transforms[index];
positionOffsets.Add(parent.InverseTransformPoint(splineTransform.TransformPoint(knot.Position)));
Quaternion knotWorldRotation = splineTransform.rotation * knot.Rotation;
Quaternion toParentRotation = Quaternion.Inverse(parent.transform.rotation) * knotWorldRotation;
rotationOffsets.Add(toParentRotation);
}
}
}
}