Files
BITFALL/Assets/Plugins/FImpossible Creations/Plugins - Shared/Math Helpers/Math/FEasing.cs

231 lines
6.1 KiB
C#
Raw Normal View History

2023-11-30 00:23:23 +08:00
using UnityEngine;
/// <summary>
/// FM: Class containing few handy easing functions
/// </summary>
public static class FEasing
{
#region Example of how to use easings
/// <summary>
/// Example how to use easing function
/// </summary>
//static System.Collections.IEnumerator Example()
//{
// float timeInSecs = 3f;
// float elapsed = 0f;
// Vector3 from = new Vector3(-1f, 2f, 1f);
// Vector3 to = new Vector3(1f, 0f, 3f);
// // Simple example with hard defined easing function
// while (elapsed < timeInSecs)
// {
// float easeValue = EaseInOutCubic(0f, 1f, elapsed / timeInSecs);
// Vector3 easedTargetVector = Vector3.Lerp(from, to, easeValue);
// yield return null;
// }
// // Example with easing function to choose
// EFease easeType = EFease.EaseInOutElastic;
// float extraValue = 1.1f;
// while (elapsed < timeInSecs)
// {
// float easeValue = GetEasingFunction(easeType)(0f, 1f, elapsed / timeInSecs, extraValue);
// Vector3 easedTargetVector = Vector3.Lerp(from, to, easeValue);
// yield return null;
// }
//}
#endregion
public enum EFease
{
EaseInCubic,
EaseOutCubic,
EaseInOutCubic,
EaseInOutElastic,
EaseInElastic,
EaseOutElastic,
EaseInExpo,
EaseOutExpo,
EaseInOutExpo,
Linear,
}
#region Easing Methods
/// <summary>
/// Cubic smooth ease, ignore argument is for delegate to work with extra arguments
/// </summary>
public static float EaseInCubic(float start, float end, float value, float ignore = 1f)
{
end -= start;
return end * value * value * value + start;
}
public static float EaseOutCubic(float start, float end, float value, float ignore = 1f)
{
value -= 1;
end -= start;
return end * (value * value * value + 1) + start;
}
public static float EaseInOutCubic(float start, float end, float value, float ignore = 1f)
{
value /= .5f;
end -= start;
if (value < 1) return end * 0.5f * value * value * value + start;
value -= 2;
return end * 0.5f * (value * value * value + 2) + start;
}
public static float EaseOutElastic(float start, float end, float value, float rangeMul = 1f)
{
end -= start;
float d = 1f;
float p = d * .3f * rangeMul;
float s;
float a = 0;
if (value == 0) return start;
if ((value /= d) == 1) return start + end;
if (a == 0f || a < Mathf.Abs(end))
{
a = end;
s = p * 0.25f * rangeMul;
}
else
{
s = p / (2 * Mathf.PI) * Mathf.Asin(end / a);
}
return (a * Mathf.Pow(2, -10 * value * rangeMul) * Mathf.Sin((value * d - s) * (2 * Mathf.PI) / p) + end + start);
}
public static float EaseInElastic(float start, float end, float value, float rangeMul = 1f)
{
end -= start;
float d = 1f;
float p = d * .3f * rangeMul;
float s;
float a = 0;
if (value == 0) return start;
if ((value /= d) == 1) return start + end;
if (a == 0f || a < Mathf.Abs(end))
{
a = end;
s = (p / 4) * rangeMul;
}
else
{
s = p / (2 * Mathf.PI) * Mathf.Asin(end / a);
}
return -(a * Mathf.Pow(2, 10 * rangeMul * (value -= 1)) * Mathf.Sin((value * d - s) * (2 * Mathf.PI) / p)) + start;
}
public static float EaseInOutElastic(float start, float end, float value, float rangeMul = 1f)
{
end -= start;
float d = 1f;
float p = d * .3f * rangeMul;
float s;
float a = 0;
if (value == 0) return start;
if ((value /= d * 0.5f) == 2) return start + end;
if (a == 0f || a < Mathf.Abs(end))
{
a = end;
s = p / 4 * rangeMul;
}
else
{
s = p / (2 * Mathf.PI) * Mathf.Asin(end / a);
}
if (value < 1) return -0.5f * (a * Mathf.Pow(2, 10 * (value -= 1)) * Mathf.Sin((value * d - s) * (2 * Mathf.PI) / p)) + start;
return a * Mathf.Pow(2, -10 * rangeMul * (value -= 1)) * Mathf.Sin((value * d - s) * (2 * Mathf.PI) / p) * 0.5f + end + start;
}
public static float EaseInExpo(float start, float end, float value, float ignore = 1f)
{
end -= start;
return end * Mathf.Pow(2, 10 * (value - 1)) + start;
}
public static float EaseOutExpo(float start, float end, float value, float ignore = 1f)
{
end -= start;
return end * (-Mathf.Pow(2, -10 * value) + 1) + start;
}
public static float EaseInOutExpo(float start, float end, float value, float ignore = 1f)
{
value /= .5f;
end -= start;
if (value < 1) return end * 0.5f * Mathf.Pow(2, 10 * (value - 1)) + start;
value--;
return end * 0.5f * (-Mathf.Pow(2, -10 * value) + 2) + start;
}
public static float Linear(float start, float end, float value, float ignore = 1f)
{
return Mathf.Lerp(start, end, value);
}
#endregion
public delegate float Function(float s, float e, float v, float extraParameter = 1f);
public static Function GetEasingFunction(EFease easingFunction)
{
if (easingFunction == EFease.EaseInCubic) return EaseInCubic;
if (easingFunction == EFease.EaseOutCubic) return EaseOutCubic;
if (easingFunction == EFease.EaseInOutCubic) return EaseInOutCubic;
if (easingFunction == EFease.EaseInElastic) return EaseInElastic;
if (easingFunction == EFease.EaseOutElastic) return EaseOutElastic;
if (easingFunction == EFease.EaseInOutElastic) return EaseInOutElastic;
if (easingFunction == EFease.EaseInExpo) return EaseInExpo;
if (easingFunction == EFease.EaseOutExpo) return EaseOutExpo;
if (easingFunction == EFease.EaseInOutExpo) return EaseInOutExpo;
if (easingFunction == EFease.Linear) return Linear;
return null;
}
}