using UnityEngine; /// /// FM: Class containing few handy easing functions /// public static class FEasing { #region Example of how to use easings /// /// Example how to use easing function /// //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 /// /// Cubic smooth ease, ignore argument is for delegate to work with extra arguments /// 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; } }