using UnityEngine; using System; using System.Collections.Generic; namespace Ichni { public enum AnimationCurveType //预设动画曲线类型 { Linear = 0, InQuad = 1, OutQuad = 2, InOutQuad = 3, InCubic = 4, OutCubic = 5, InOutCubic = 6, InQuart = 7, OutQuart = 8, InOutQuart = 9, InQuint = 10, OutQuint = 11, InOutQuint = 12, InSine = 13, OutSine = 14, InOutSine = 15, InExpo = 16, OutExpo = 17, InOutExpo = 18, InCirc = 19, OutCirc = 20, InOutCirc = 21, InBounce = 22, OutBounce = 23, InOutBounce = 24, InElastic = 25, OutElastic = 26, InOutElastic = 27, InBack = 28, OutBack = 29, InOutBack = 30 } public static class AnimationCurveEvaluator { public static float Evaluate(AnimationCurveType animationCurveType, float t) { t = Mathf.Clamp(t, 0, 1); switch (animationCurveType) { case AnimationCurveType.Linear: return Linear(0, 1, t); case AnimationCurveType.InQuad: return InQuad(0, 1, t); case AnimationCurveType.OutQuad: return OutQuad(0, 1, t); case AnimationCurveType.InOutQuad: return InOutQuad(0, 1, t); case AnimationCurveType.InCubic: return InCubic(0, 1, t); case AnimationCurveType.OutCubic: return OutCubic(0, 1, t); case AnimationCurveType.InOutCubic: return InOutCubic(0, 1, t); case AnimationCurveType.InQuart: return InQuart(0, 1, t); case AnimationCurveType.OutQuart: return OutQuart(0, 1, t); case AnimationCurveType.InOutQuart: return InOutQuart(0, 1, t); case AnimationCurveType.InQuint: return InQuint(0, 1, t); case AnimationCurveType.OutQuint: return OutQuint(0, 1, t); case AnimationCurveType.InOutQuint: return InOutQuint(0, 1, t); case AnimationCurveType.InSine: return InSine(0, 1, t); case AnimationCurveType.OutSine: return OutSine(0, 1, t); case AnimationCurveType.InOutSine: return InOutSine(0, 1, t); case AnimationCurveType.InExpo: return InExpo(0, 1, t); case AnimationCurveType.OutExpo: return OutExpo(0, 1, t); case AnimationCurveType.InOutExpo: return InOutExpo(0, 1, t); case AnimationCurveType.InCirc: return InCirc(0, 1, t); case AnimationCurveType.OutCirc: return OutCirc(0, 1, t); case AnimationCurveType.InOutCirc: return InOutCirc(0, 1, t); case AnimationCurveType.InBounce: return InBounce(0, 1, t); case AnimationCurveType.OutBounce: return OutBounce(0, 1, t); case AnimationCurveType.InOutBounce: return InOutBounce(0, 1, t); case AnimationCurveType.InElastic: return InElastic(0, 1, t); case AnimationCurveType.OutElastic: return OutElastic(0, 1, t); case AnimationCurveType.InOutElastic: return InOutElastic(0, 1, t); case AnimationCurveType.InBack: return InBack(0, 1, t); case AnimationCurveType.OutBack: return OutBack(0, 1, t); case AnimationCurveType.InOutBack: return InOutBack(0, 1, t); } throw new NotImplementedException($"Animation curve type {animationCurveType} is not implemented."); } #region 缓动曲线计算式 private static float Linear(float from, float to, float t) { float c = to - from; t /= 1f; return c * t / 1f + from; } private static float InQuad(float from, float to, float t) { float c = to - from; t /= 1f; return c * t * t + from; } private static float OutQuad(float from, float to, float t) { float c = to - from; t /= 1f; return -c * t * (t - 2f) + from; } private static float InOutQuad(float from, float to, float t) { float c = to - from; t /= 0.5f; if (t < 1) return c / 2f * t * t + from; t--; return -c / 2f * (t * (t - 2) - 1) + from; } private static float InCubic(float from, float to, float t) { float c = to - from; t /= 1f; return c * t * t * t + from; } private static float OutCubic(float from, float to, float t) { float c = to - from; t /= 1f; t--; return c * (t * t * t + 1) + from; } private static float InOutCubic(float from, float to, float t) { float c = to - from; t /= 0.5f; if (t < 1) return c / 2f * t * t * t + from; t -= 2; return c / 2f * (t * t * t + 2) + from; } private static float InQuart(float from, float to, float t) { float c = to - from; t /= 1f; return c * t * t * t * t + from; } private static float OutQuart(float from, float to, float t) { float c = to - from; t /= 1f; t--; return -c * (t * t * t * t - 1) + from; } private static float InOutQuart(float from, float to, float t) { float c = to - from; t /= 0.5f; if (t < 1) return c / 2f * t * t * t * t + from; t -= 2; return -c / 2f * (t * t * t * t - 2) + from; } private static float InQuint(float from, float to, float t) { float c = to - from; t /= 1f; return c * t * t * t * t * t + from; } private static float OutQuint(float from, float to, float t) { float c = to - from; t /= 1f; t--; return c * (t * t * t * t * t + 1) + from; } private static float InOutQuint(float from, float to, float t) { float c = to - from; t /= 0.5f; if (t < 1) return c / 2f * t * t * t * t * t + from; t -= 2; return c / 2f * (t * t * t * t * t + 2) + from; } private static float InSine(float from, float to, float t) { float c = to - from; return -c * Mathf.Cos(t / 1f * (Mathf.PI / 2f)) + c + from; } private static float OutSine(float from, float to, float t) { float c = to - from; return c * Mathf.Sin(t / 1f * (Mathf.PI / 2f)) + from; } private static float InOutSine(float from, float to, float t) { float c = to - from; return -c / 2f * (Mathf.Cos(Mathf.PI * t / 1f) - 1) + from; } private static float InExpo(float from, float to, float t) { float c = to - from; return c * Mathf.Pow(2, 10 * (t / 1f - 1)) + from; } private static float OutExpo(float from, float to, float t) { float c = to - from; return c * (-Mathf.Pow(2, -10 * t / 1f) + 1) + from; } private static float InOutExpo(float from, float to, float t) { float c = to - from; t /= 0.5f; if (t < 1f) return c / 2f * Mathf.Pow(2, 10 * (t - 1)) + from; t--; return c / 2f * (-Mathf.Pow(2, -10 * t) + 2) + from; } private static float InCirc(float from, float to, float t) { float c = to - from; t /= 1f; return -c * (Mathf.Sqrt(1 - t * t) - 1) + from; } private static float OutCirc(float from, float to, float t) { float c = to - from; t /= 1f; t--; return c * Mathf.Sqrt(1 - t * t) + from; } private static float InOutCirc(float from, float to, float t) { float c = to - from; t /= 0.5f; if (t < 1) return -c / 2f * (Mathf.Sqrt(1 - t * t) - 1) + from; t -= 2; return c / 2f * (Mathf.Sqrt(1 - t * t) + 1) + from; } private static float InBounce(float from, float to, float t) { float c = to - from; return c - OutBounce(0f, c, 1f - t) + from; //does this work? } private static float OutBounce(float from, float to, float t) { float c = to - from; if ((t /= 1f) < (1 / 2.75f)) { return c * (7.5625f * t * t) + from; } else if (t < (2 / 2.75f)) { return c * (7.5625f * (t -= (1.5f / 2.75f)) * t + .75f) + from; } else if (t < (2.5 / 2.75)) { return c * (7.5625f * (t -= (2.25f / 2.75f)) * t + .9375f) + from; } else { return c * (7.5625f * (t -= (2.625f / 2.75f)) * t + .984375f) + from; } } private static float InOutBounce(float from, float to, float t) { float c = to - from; if (t < 0.5f) return InBounce(0, c, t * 2f) * 0.5f + from; return OutBounce(0, c, t * 2 - 1) * 0.5f + c * 0.5f + from; } private static float InElastic(float from, float to, float t) { float c = to - from; if (t == 0) return from; if ((t /= 1f) == 1) return from + c; float p = 0.3f; float s = p / 4f; return -(c * Mathf.Pow(2, 10 * (t -= 1)) * Mathf.Sin((t - s) * (2 * Mathf.PI) / p)) + from; } private static float OutElastic(float from, float to, float t) { float c = to - from; if (t == 0) return from; if ((t /= 1f) == 1) return from + c; float p = 0.3f; float s = p / 4f; return (c * Mathf.Pow(2, -10 * t) * Mathf.Sin((t - s) * (2 * Mathf.PI) / p) + c + from); } private static float InOutElastic(float from, float to, float t) { float c = to - from; if (t == 0) return from; if ((t /= 0.5f) == 2) return from + c; float p = 0.3f * 1.5f; float s = p / 4f; if (t < 1) return -0.5f * (c * Mathf.Pow(2, 10 * (t -= 1f)) * Mathf.Sin((t - 2) * (2 * Mathf.PI) / p)) + from; return c * Mathf.Pow(2, -10 * (t -= 1)) * Mathf.Sin((t - s) * (2f * Mathf.PI) / p) * 0.5f + c + from; } private static float InBack(float from, float to, float t) { float c = to - from; float s = 1.70158f; t /= 0.5f; return c * t * t * ((s + 1) * t - s) + from; } private static float OutBack(float from, float to, float t) { float c = to - from; float s = 1.70158f; t = t / 1f - 1f; return c * (t * t * ((s + 1) * t + s) + 1) + from; } private static float InOutBack(float from, float to, float t) { float c = to - from; float s = 1.70158f; t /= 0.5f; if (t < 1) return c / 2f * (t * t * (((s *= (1.525f)) + 1) * t - s)) + from; t -= 2; return c / 2f * (t * t * (((s *= (1.525f)) + 1) * t + s) + 2) + from; } #endregion } // [System.Serializable] // public class PresetAnimationCurve // { // public AnimationCurveType animationCurveType; //动画曲线类型 // // public PresetAnimationCurve(AnimationCurveType animationCurveType) // { // this.animationCurveType = animationCurveType; // } // // /// // /// 根据Type选择曲线,并计算t点(0,1)时曲线的值,若t越界,则直接返回0或1 // /// // public float Evaluate(float t) // { // return AnimationCurveEvaluator.Evaluate(this.animationCurveType, t); // } // } }