LunarInfantry/Assets/Core Extensions & Helpers/SplineExtensions.cs
2026-01-02 01:31:54 -08:00

87 lines
3.7 KiB
C#
Executable file

using UnityEngine;
using Unity.Mathematics;
using UnityEngine.Splines;
namespace Core.Extensions
{
[System.Serializable]
public class SplinePathSettings
{
static Vector2 CalculatedWorldCenter;
[SerializeField] public bool PreventOverride;
[SerializeField] public bool UseOwnerTransformAsWorldCenter;
public Vector2 WorldCenter => PreventOverride ? WorldCenterOverride : WorldCenterOverride;
public Vector2 WorldCenterOverride;
public float RB_MaxSpeed;
public float RB_Acceleration;
public bool Looping;
public float PathUpdateDistance;
public float PathForceRecalculateDistance;
[HideInInspector] public Vector2 CalculatedTargetPosition;
public float CurrentLerpValue;
public static void SetWorldCenter(Vector2 v)
{
CalculatedWorldCenter = v;
}
public void UseTransformAsWorldCenter(Vector2 v, bool forced)
{
if (UseOwnerTransformAsWorldCenter || forced)
{
UseOwnerTransformAsWorldCenter = true;
this.WorldCenterOverride = v;
PreventOverride = false;
Helper.Repaint();
}
}
public void ClearWorldCenterOverride()
{
WorldCenterOverride = Vector2.zero;
UseOwnerTransformAsWorldCenter = false;
PreventOverride = true;
Helper.Repaint();
}
}
public static class SplineExtensions
{
private static Vector2 BremseEvaluateLerp(this Spline path, Vector2 worldCenter, float lerp, bool looping = false)
{
Vector2 evaluatePosition = new();
if (path.EvaluatePosition(looping ? lerp % 1f : lerp) is float3 f)
{
evaluatePosition.x = f.x; evaluatePosition.y = f.y;
evaluatePosition += worldCenter;
}
return evaluatePosition;
}
public static float BremseGetLength(this Spline path)
{
float length = 0f;
for (int i = 0; i < path.Count; i++)
{
length += path.GetCurveLength(i);
}
return length;
}
public static Vector2 LerpPosition(this Spline path, Vector2 worldCenter, float lerp, bool looping = false)
{
return BremseEvaluateLerp(path, worldCenter, lerp, looping);
}
public static Vector2 LerpPositionWithTime(this Spline path, Vector2 worldCenter, float time, bool looping = false)
{
return BremseEvaluateLerp(path, worldCenter, time / path.BremseGetLength(), looping);
}
public static Rigidbody2D RunAlongSpline(this Rigidbody2D rb, Spline path, SplinePathSettings settings)
{
if (settings.CalculatedTargetPosition.SquareDistanceToGreaterThan(rb.position, settings.PathForceRecalculateDistance))
{
settings.CalculatedTargetPosition = path.LerpPosition(settings.WorldCenter, settings.CurrentLerpValue, settings.Looping);
}
else if (settings.CalculatedTargetPosition.SquareDistanceToLessThan(rb.position, settings.PathUpdateDistance.Max(0.1f)))
{
settings.CurrentLerpValue += Time.deltaTime;
settings.CalculatedTargetPosition = path.LerpPosition(settings.WorldCenter, settings.CurrentLerpValue, settings.Looping);
}
rb.VelocityTowards((settings.CalculatedTargetPosition - rb.position).ScaleToMagnitude(settings.RB_MaxSpeed), settings.RB_Acceleration.Max(0.5f));
return rb;
}
}
}