70 lines
2.5 KiB
C#
70 lines
2.5 KiB
C#
using System;
|
|
using UnityEngine;
|
|
|
|
namespace Cryville.Common.Unity {
|
|
public class PropertyTweener<T> {
|
|
readonly Func<T> _getter;
|
|
readonly Action<T> _setter;
|
|
readonly Tweener<T> _tweener;
|
|
public PropertyTweener(Func<T> getter, Action<T> setter, Tweener<T> tweener) {
|
|
_getter = getter;
|
|
_setter = setter;
|
|
_tweener = tweener;
|
|
}
|
|
public PropertyTweener<T> Start(T endValue, float duration) {
|
|
_tweener.Start(_getter(), endValue, duration);
|
|
return this;
|
|
}
|
|
public void Advance(float deltaTime) {
|
|
_setter(_tweener.Advance(deltaTime));
|
|
}
|
|
}
|
|
public class Tweener<T> {
|
|
readonly Func<T, T, T> _addition;
|
|
readonly Func<float, T, T> _multiplication;
|
|
public Tweener(Func<T, T, T> addition, Func<float, T, T> multiplication) {
|
|
_addition = addition;
|
|
_multiplication = multiplication;
|
|
}
|
|
public Func<float, float> EasingFunction { get; set; } = EasingFunctions.Linear;
|
|
public Tweener<T> SetEasingFunction(Func<float, float> easing) {
|
|
EasingFunction = easing;
|
|
return this;
|
|
}
|
|
|
|
T _startValue = default;
|
|
T _endValue = default;
|
|
float _duration = float.PositiveInfinity;
|
|
float _time;
|
|
public Tweener<T> Start(T startValue, T endValue, float duration) {
|
|
_startValue = startValue;
|
|
_endValue = endValue;
|
|
_duration = duration;
|
|
_time = 0;
|
|
return this;
|
|
}
|
|
public T Advance(float deltaTime) {
|
|
_time += deltaTime;
|
|
var ratio = EasingFunction(Math.Clamp(_time / _duration, 0, 1));
|
|
return _addition(_multiplication(1 - ratio, _startValue), _multiplication(ratio, _endValue));
|
|
}
|
|
}
|
|
public static class Tweeners {
|
|
public static Tweener<int> Int32 => new((a, b) => a + b, (k, v) => (int)(k * v));
|
|
public static Tweener<float> Single => new((a, b) => a + b, (k, v) => k * v);
|
|
public static Tweener<double> Double => new((a, b) => a + b, (k, v) => k * v);
|
|
public static Tweener<Vector2> Vector2 => new((a, b) => a + b, (k, v) => k * v);
|
|
public static Tweener<Vector3> Vector3 => new((a, b) => a + b, (k, v) => k * v);
|
|
public static Tweener<Quaternion> Quaternion => new((a, b) => a * b, (k, v) => UnityEngine.Quaternion.Slerp(UnityEngine.Quaternion.identity, v, k));
|
|
}
|
|
public static class EasingFunctions {
|
|
public static float Linear(float x) => x;
|
|
public static float InQuad(float x) => x * x;
|
|
public static float InCubic(float x) => x * x * x;
|
|
public static float InSine(float x) => 1 - OutSine(1 - x);
|
|
public static float OutQuad(float x) => 1 - InQuad(1 - x);
|
|
public static float OutCubic(float x) => 1 - InCubic(1 - x);
|
|
public static float OutSine(float x) => MathF.Sin(x * MathF.PI / 2);
|
|
}
|
|
}
|