Skip to content

Instantly share code, notes, and snippets.

@krooq
Created September 4, 2022 01:12
Show Gist options
  • Save krooq/5f05b8757e0aaeb8e0d31b56242ec000 to your computer and use it in GitHub Desktop.
Save krooq/5f05b8757e0aaeb8e0d31b56242ec000 to your computer and use it in GitHub Desktop.
using System;
using Unity.Mathematics;
using UnityEngine;
namespace Krooq.Core
{
[Serializable]
public struct FloatAnimation
{
[HideInInspector] public float Value;
[HideInInspector] public float StartValue;
[HideInInspector] public float EndValue;
[HideInInspector] public float Elapsed;
public float Duration;
public EasingMode Curve;
public static FloatAnimation Constant(float value) => new()
{
Value = value,
StartValue = value,
EndValue = value,
Curve = EasingMode.Linear
};
public FloatAnimation(float startValue, float endValue, float duration, EasingMode curve)
{
Value = 0;
Elapsed = 0;
StartValue = startValue;
EndValue = endValue;
Duration = math.max(duration, 0);
Curve = curve;
}
public FloatAnimation Tick(float deltaTime)
{
Elapsed += deltaTime;
return this;
}
public float Evaluate()
{
var t = Duration > 0 ? math.saturate(Elapsed / Duration) : 0;
var easedProgress = Curve.Evaluate(t);
Value = math.lerp(StartValue, EndValue, easedProgress);
return Value;
}
public static implicit operator float(FloatAnimation floatAnimation) => floatAnimation.Evaluate();
}
[Serializable]
public struct Float3Animation
{
[HideInInspector] public float3 Value;
[HideInInspector] public float3 StartValue;
[HideInInspector] public float3 EndValue;
[HideInInspector] public float Elapsed;
public float Duration;
public EasingMode Curve;
public static Float3Animation Constant(float3 value) => new()
{
Value = value,
StartValue = value,
EndValue = value,
Curve = EasingMode.Linear
};
public Float3Animation(float3 startValue, float3 endValue, float duration, EasingMode curve)
{
Value = 0;
Elapsed = 0;
StartValue = startValue;
EndValue = endValue;
Duration = math.max(duration, 0);
Curve = curve;
}
public Float3Animation Tick(float deltaTime)
{
Elapsed += deltaTime;
return this;
}
public float3 Evaluate()
{
var t = Duration > 0 ? math.saturate(Elapsed / Duration) : 0;
var easedProgress = Curve.Evaluate(t);
Value = math.lerp(StartValue, EndValue, easedProgress);
return Value;
}
public static implicit operator float3(Float3Animation float3Animation) => float3Animation.Evaluate();
}
public enum EasingMode
{
Ease,
EaseIn,
EaseOut,
EaseInOut,
Linear,
EaseInSine,
EaseOutSine,
EaseInOutSine,
EaseInCubic,
EaseOutCubic,
EaseInOutCubic,
EaseInCirc,
EaseOutCirc,
EaseInOutCirc,
EaseInElastic,
EaseOutElastic,
EaseInOutElastic,
EaseInBack,
EaseOutBack,
EaseInOutBack,
EaseInBounce,
EaseOutBounce,
EaseInOutBounce,
}
public static class Easing
{
private const float HalfPi = 1.570796f;
public static float Step(float t) => t < 0.5 ? 0.0f : 1f;
public static float Linear(float t) => t;
public static float InSine(float t) => Mathf.Sin((float)(1.57079637050629 * (t - 1.0))) + 1f;
public static float OutSine(float t) => Mathf.Sin(t * 1.570796f);
public static float InOutSine(float t) =>
(float)((Mathf.Sin((float)(3.14159274101257 * (t - 0.5))) + 1.0) * 0.5);
public static float InQuad(float t) => t * t;
public static float OutQuad(float t) => t * (2f - t);
public static float InOutQuad(float t)
{
t *= 2f;
return t < 1.0
? (float)(t * (double)t * 0.5)
: (float)(-0.5 * ((t - 1.0) * (t - 3.0) - 1.0));
}
public static float InCubic(float t) => InPower(t, 3);
public static float OutCubic(float t) => OutPower(t, 3);
public static float InOutCubic(float t) => InOutPower(t, 3);
public static float InPower(float t, int power) => Mathf.Pow(t, power);
public static float OutPower(float t, int power)
{
var num = power % 2 == 0 ? -1 : 1;
return num * (Mathf.Pow(t - 1f, power) + num);
}
public static float InOutPower(float t, int power)
{
t *= 2f;
if (t < 1.0)
return InPower(t, power) * 0.5f;
var num = power % 2 == 0 ? -1 : 1;
return (float)(num * 0.5 * (Mathf.Pow(t - 2f, power) + (double)(num * 2)));
}
public static float InBounce(float t) => 1f - OutBounce(1f - t);
public static float OutBounce(float t)
{
if (t < 0.363636374473572)
return 121f / 16f * t * t;
if (t < 0.727272748947144)
return (float)(121.0 / 16.0 * (t -= 0.5454546f) * t + 0.75);
return t < 0.909090936183929
? (float)(121.0 / 16.0 * (t -= 0.8181818f) * t + 15.0 / 16.0)
: (float)(121.0 / 16.0 * (t -= 0.9545454f) * t + 63.0 / 64.0);
}
public static float InOutBounce(float t) =>
t < 0.5 ? InBounce(t * 2f) * 0.5f : (float)(OutBounce((float)((t - 0.5) * 2.0)) * 0.5 + 0.5);
public static float InElastic(float t)
{
if (t == 0.0)
return 0.0f;
if (t == 1.0)
return 1f;
var num1 = 0.3f;
var num2 = num1 / 4f;
return (float)-(Mathf.Pow(2f, 10f * --t) *
(double)Mathf.Sin((float)((t - (double)num2) * 6.28318548202515) / num1));
}
public static float OutElastic(float t)
{
if (t == 0.0)
return 0.0f;
if (t == 1.0)
return 1f;
var num1 = 0.3f;
var num2 = num1 / 4f;
return (float)(Mathf.Pow(2f, -10f * t) *
(double)Mathf.Sin((float)((t - (double)num2) * 6.28318548202515) / num1) + 1.0);
}
public static float InOutElastic(float t) =>
t < 0.5 ? InElastic(t * 2f) * 0.5f : (float)(OutElastic((float)((t - 0.5) * 2.0)) * 0.5 + 0.5);
public static float InBack(float t)
{
var num = 1.70158f;
return (float)(t * (double)t * ((num + 1.0) * t - num));
}
public static float OutBack(float t) => 1f - InBack(1f - t);
public static float InOutBack(float t) =>
t < 0.5 ? InBack(t * 2f) * 0.5f : (float)(OutBack((float)((t - 0.5) * 2.0)) * 0.5 + 0.5);
public static float InBack(float t, float s) => (float)(t * (double)t * ((s + 1.0) * t - s));
public static float OutBack(float t, float s) => 1f - InBack(1f - t, s);
public static float InOutBack(float t, float s) =>
t < 0.5 ? InBack(t * 2f, s) * 0.5f : (float)(OutBack((float)((t - 0.5) * 2.0), s) * 0.5 + 0.5);
public static float InCirc(float t) => (float)-(Mathf.Sqrt((float)(1.0 - t * (double)t)) - 1.0);
public static float OutCirc(float t)
{
--t;
return Mathf.Sqrt((float)(1.0 - t * (double)t));
}
public static float InOutCirc(float t)
{
t *= 2f;
if (t < 1.0)
return (float)(-0.5 * (Mathf.Sqrt((float)(1.0 - t * (double)t)) - 1.0));
t -= 2f;
return (float)(0.5 * (Mathf.Sqrt((float)(1.0 - t * (double)t)) + 1.0));
}
public static float Evaluate(this EasingMode mode, float t) => mode.TransitionFunction()(t);
public static Func<float, float> TransitionFunction(this EasingMode mode)
{
return mode switch
{
EasingMode.EaseIn => InQuad,
EasingMode.EaseOut => OutQuad,
EasingMode.EaseInOut => InOutQuad,
EasingMode.Linear => Linear,
EasingMode.EaseInSine => InSine,
EasingMode.EaseOutSine => OutSine,
EasingMode.EaseInOutSine => InOutSine,
EasingMode.EaseInCubic => InCubic,
EasingMode.EaseOutCubic => OutCubic,
EasingMode.EaseInOutCubic => InOutCubic,
EasingMode.EaseInCirc => InCirc,
EasingMode.EaseOutCirc => OutCirc,
EasingMode.EaseInOutCirc => InOutCirc,
EasingMode.EaseInElastic => InElastic,
EasingMode.EaseOutElastic => OutElastic,
EasingMode.EaseInOutElastic => InOutElastic,
EasingMode.EaseInBack => InBack,
EasingMode.EaseOutBack => OutBack,
EasingMode.EaseInOutBack => InOutBack,
EasingMode.EaseInBounce => InBounce,
EasingMode.EaseOutBounce => OutBounce,
EasingMode.EaseInOutBounce => InOutBounce,
_ => t => t * (float)(1.79999995231628 + t * (t * -0.200000002980232 - 0.600000023841858))
};
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment