87 lines
3.7 KiB
C#
Executable file
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;
|
|
}
|
|
}
|
|
}
|