using UnityEngine; using System.Collections; using System; using System.Collections.Generic; public static class MyTween { private delegate float FloatEasingFunction(float start,float end,float value); private delegate Vector3 Vector3EasingFunction(Vector3 start,Vector3 end,float value); public enum CoordinateSystem : byte { Local, Global } public enum Ease : byte { easeInQuad, easeOutQuad, easeInOutQuad, easeInCubic, easeOutCubic, easeInOutCubic, easeInQuart, easeOutQuart, easeInOutQuart, easeInQuint, easeOutQuint, easeInOutQuint, easeInSine, easeOutSine, easeInOutSine, easeInExpo, easeOutExpo, easeInOutExpo, easeInCirc, easeOutCirc, easeInOutCirc, linear, spring, easeInBounce, easeOutBounce, easeInOutBounce, easeInBack, easeOutBack, easeInOutBack, easeInElastic, easeOutElastic, easeInOutElastic, } public enum Loop : byte { none, loop, pingPong } enum VectorComponent : byte { x, y, z } //static Dictionary static List _stopAnimationList = new List(); static int _nextAnimationId; static float GetDeltaTime(bool useRealTime, ref float lastRealTime) { float delta; if (useRealTime) { delta = Time.realtimeSinceStartup - lastRealTime; lastRealTime = Time.realtimeSinceStartup; } else { delta = Time.deltaTime; } return delta; } public static void StopAnimation(this MonoBehaviour mb, int animationId) { //can't start coroutines if inactive if (!mb.gameObject.activeInHierarchy) { return; } _stopAnimationList.Add(animationId); mb.StartCoroutine(ClearJustInCaseAnimDidNotExist(animationId)); } static IEnumerator ClearJustInCaseAnimDidNotExist(int animationId) { yield return null; //wait a frame, so if the animation existed then it would have been handled ShouldStop(animationId); } public static bool ShouldStop(int id) { for (int i = 0; i < _stopAnimationList.Count; i++) { if (_stopAnimationList[i] == id) { _stopAnimationList.RemoveAt(i); return true; } } return false; } #region Movement public static int MoveFrom(this MonoBehaviour mb, Vector3 moveFrom, float time, float delay = 0, CoordinateSystem coordinateSystem = CoordinateSystem.Global, Ease ease = Ease.easeOutCubic, Action OnComplete = null, Loop loop = Loop.none, int numOfLoops = int.MaxValue, bool useRealTime = false) { Transform t = mb.transform; Vector3 moveTo; if (coordinateSystem == CoordinateSystem.Global) { moveTo = t.position; t.position = moveFrom; } else { moveTo = t.localPosition; t.localPosition = moveFrom; } mb.StartCoroutine(MoveToCoroutine(++_nextAnimationId, t, moveTo, time, delay, coordinateSystem, ease, OnComplete, loop, numOfLoops, useRealTime)); return _nextAnimationId; } public static int MoveTo(this MonoBehaviour mb, Vector3 pos, float time, float delay = 0, CoordinateSystem coordinateSystem = CoordinateSystem.Global, Ease ease = Ease.easeOutCubic, Action OnComplete = null, Loop loop = Loop.none, int numOfLoops = int.MaxValue, bool useRealTime = false) { mb.StartCoroutine(MoveToCoroutine(++_nextAnimationId, mb.transform, pos, time, delay, coordinateSystem, ease, OnComplete, loop, numOfLoops, useRealTime)); return _nextAnimationId; } public static int MoveXTo(this MonoBehaviour mb, float x, float time, float delay = 0, CoordinateSystem coordinateSystem = CoordinateSystem.Global, Ease ease = Ease.easeOutCubic, Action OnComplete = null, Loop loop = Loop.none, int numOfLoops = int.MaxValue, bool useRealTime = false) { mb.StartCoroutine(MoveComponentToCoroutine(++_nextAnimationId, mb.transform, x, VectorComponent.x, time, delay, coordinateSystem, ease, OnComplete, loop, numOfLoops, useRealTime)); return _nextAnimationId; } public static int MoveYTo(this MonoBehaviour mb, float y, float time, float delay = 0, CoordinateSystem coordinateSystem = CoordinateSystem.Global, Ease ease = Ease.easeOutCubic, Action OnComplete = null, Loop loop = Loop.none, int numOfLoops = int.MaxValue, bool useRealTime = false) { mb.StartCoroutine(MoveComponentToCoroutine(++_nextAnimationId, mb.transform, y, VectorComponent.y, time, delay, coordinateSystem, ease, OnComplete, loop, numOfLoops, useRealTime)); return _nextAnimationId; } public static int MoveZTo(this MonoBehaviour mb, float z, float time, float delay = 0, CoordinateSystem coordinateSystem = CoordinateSystem.Global, Ease ease = Ease.easeOutCubic, Action OnComplete = null, Loop loop = Loop.none, int numOfLoops = int.MaxValue, bool useRealTime = false) { mb.StartCoroutine(MoveComponentToCoroutine(++_nextAnimationId, mb.transform, z, VectorComponent.z, time, delay, coordinateSystem, ease, OnComplete, loop, numOfLoops, useRealTime)); return _nextAnimationId; } public static int MoveBy(this MonoBehaviour mb, Vector3 pos, float time, float delay = 0, CoordinateSystem coordinateSystem = CoordinateSystem.Global, Ease ease = Ease.easeOutCubic, Action OnComplete = null, Loop loop = Loop.none, int numOfLoops = int.MaxValue, bool useRealTime = false) { Transform t = mb.transform; if (coordinateSystem == CoordinateSystem.Local) { pos += t.localPosition; } else { pos += t.position; } mb.StartCoroutine(MoveToCoroutine(++_nextAnimationId, t, pos, time, delay, coordinateSystem, ease, OnComplete, loop, numOfLoops, useRealTime)); return _nextAnimationId; } static IEnumerator MoveToCoroutine(int id, Transform transform, Vector3 endPos, float time, float delay, CoordinateSystem coordinateSystem, Ease ease, Action OnComplete, Loop loop, int numOfLoops, bool useRealTime) { if (delay > 0) { yield return new WaitForSeconds(delay); } float timeSoFar = 0; float percentage = 0; Vector3 startPos = coordinateSystem == CoordinateSystem.Local ? transform.localPosition : transform.position; bool reverse = false; bool playing = true; float lastRealTime = Time.realtimeSinceStartup; while (playing) { if (reverse) { timeSoFar -= GetDeltaTime(useRealTime, ref lastRealTime); percentage = timeSoFar / time; if (percentage < 0) { timeSoFar = 0; percentage = 0; reverse = false; --numOfLoops; if (numOfLoops == 0) { playing = false; } } } else { timeSoFar += GetDeltaTime(useRealTime, ref lastRealTime); percentage = timeSoFar / time; if (percentage > 1) { if (loop == Loop.loop) { --numOfLoops; if (numOfLoops > 0) { timeSoFar = 0; percentage = 0; } else { percentage = 1; playing = false; } } else if (loop == Loop.pingPong) { timeSoFar = time; percentage = 1; reverse = true; } else { percentage = 1; playing = false; } } } Vector3EasingFunction easeFunc = GetVector3EasingFunction(ease); Vector3 newPos = easeFunc(startPos, endPos, percentage); if (coordinateSystem == CoordinateSystem.Local) { transform.localPosition = newPos; } else { transform.position = newPos; } yield return null; if (ShouldStop(id)) { yield break; } } if (OnComplete != null) { OnComplete(); } } static IEnumerator MoveComponentToCoroutine(int id, Transform transform, float endPos, VectorComponent component, float time, float delay, CoordinateSystem coordinateSystem, Ease ease, Action OnComplete, Loop loop, int numOfLoops, bool useRealTime) { if (delay > 0) { yield return new WaitForSeconds(delay); } float timeSoFar = 0; float percentage = 0; Vector3 start = coordinateSystem == CoordinateSystem.Local ? transform.localPosition : transform.position; float startPos = 0; switch (component) { case VectorComponent.x: startPos = start.x; break; case VectorComponent.y: startPos = start.y; break; case VectorComponent.z: startPos = start.z; break; } bool reverse = false; bool playing = true; float lastRealTime = Time.realtimeSinceStartup; while (playing) { if (reverse) { timeSoFar -= GetDeltaTime(useRealTime, ref lastRealTime); percentage = timeSoFar / time; if (percentage < 0) { timeSoFar = 0; percentage = 0; reverse = false; --numOfLoops; if (numOfLoops == 0) { playing = false; } } } else { timeSoFar += GetDeltaTime(useRealTime, ref lastRealTime); percentage = timeSoFar / time; if (percentage > 1) { if (loop == Loop.loop) { --numOfLoops; if (numOfLoops > 0) { timeSoFar = 0; percentage = 0; } else { percentage = 1; playing = false; } } else if (loop == Loop.pingPong) { timeSoFar = time; percentage = 1; reverse = true; } else { percentage = 1; playing = false; } } } FloatEasingFunction easeFunc = GetFloatEasingFunction(ease); float newComponent = easeFunc(startPos, endPos, percentage); Vector3 newPos = coordinateSystem == CoordinateSystem.Local ? transform.localPosition : transform.position; switch (component) { case VectorComponent.x: newPos.x = newComponent; break; case VectorComponent.y: newPos.y = newComponent; break; case VectorComponent.z: newPos.z = newComponent; break; } if (coordinateSystem == CoordinateSystem.Local) { transform.localPosition = newPos; } else { transform.position = newPos; } yield return null; if (ShouldStop(id)) { yield break; } } if (OnComplete != null) { OnComplete(); } } #endregion #region Scale public static int ScaleFrom(this MonoBehaviour mb, Vector3 scaleFrom, float time, float delay = 0, Ease ease = Ease.easeOutCubic, Action OnComplete = null, Loop loop = Loop.none, int numOfLoops = int.MaxValue, bool useRealTime = false) { Transform t = mb.transform; Vector3 scaleTo = t.localScale; t.localScale = scaleFrom; mb.StartCoroutine(ScaleToCoroutine(++_nextAnimationId, t, scaleTo, time, delay, ease, OnComplete, loop, numOfLoops, useRealTime)); return _nextAnimationId; } public static int ScaleTo(this MonoBehaviour mb, Vector3 scale, float time, float delay = 0, Ease ease = Ease.easeOutCubic, Action OnComplete = null, Loop loop = Loop.none, int numOfLoops = int.MaxValue, bool useRealTime = false) { mb.StartCoroutine(ScaleToCoroutine(++_nextAnimationId, mb.transform, scale, time, delay, ease, OnComplete, loop, numOfLoops, useRealTime)); return _nextAnimationId; } public static int ScaleXTo(this MonoBehaviour mb, float x, float time, float delay = 0, Ease ease = Ease.easeOutCubic, Action OnComplete = null, Loop loop = Loop.none, int numOfLoops = int.MaxValue, bool useRealTime = false) { mb.StartCoroutine(ScaleComponentToCoroutine(++_nextAnimationId, mb.transform, x, VectorComponent.x, time, delay, ease, OnComplete, loop, numOfLoops, useRealTime)); return _nextAnimationId; } public static int ScaleYTo(this MonoBehaviour mb, float y, float time, float delay = 0, Ease ease = Ease.easeOutCubic, Action OnComplete = null, Loop loop = Loop.none, int numOfLoops = int.MaxValue, bool useRealTime = false) { mb.StartCoroutine(ScaleComponentToCoroutine(++_nextAnimationId, mb.transform, y, VectorComponent.y, time, delay, ease, OnComplete, loop, numOfLoops, useRealTime)); return _nextAnimationId; } public static int ScaleZTo(this MonoBehaviour mb, float z, float time, float delay = 0, Ease ease = Ease.easeOutCubic, Action OnComplete = null, Loop loop = Loop.none, int numOfLoops = int.MaxValue, bool useRealTime = false) { mb.StartCoroutine(ScaleComponentToCoroutine(++_nextAnimationId, mb.transform, z, VectorComponent.z, time, delay, ease, OnComplete, loop, numOfLoops, useRealTime)); return _nextAnimationId; } static IEnumerator ScaleToCoroutine(int id, Transform transform, Vector3 endScale, float time, float delay, Ease ease, Action OnComplete, Loop loop, int numOfLoops, bool useRealTime) { if (delay > 0) { yield return new WaitForSeconds(delay); } float timeSoFar = 0; float percentage = 0; Vector3 startScale = transform.localScale; bool reverse = false; bool playing = true; float lastRealTime = Time.realtimeSinceStartup; while (playing) { if (reverse) { timeSoFar -= GetDeltaTime(useRealTime, ref lastRealTime); percentage = timeSoFar / time; if (percentage < 0) { timeSoFar = 0; percentage = 0; reverse = false; --numOfLoops; if (numOfLoops == 0) { playing = false; } } } else { timeSoFar += GetDeltaTime(useRealTime, ref lastRealTime); percentage = timeSoFar / time; if (percentage > 1) { if (loop == Loop.loop) { --numOfLoops; if (numOfLoops > 0) { timeSoFar = 0; percentage = 0; } else { percentage = 1; playing = false; } } else if (loop == Loop.pingPong) { timeSoFar = time; percentage = 1; reverse = true; } else { percentage = 1; playing = false; } } } Vector3EasingFunction easeFunc = GetVector3EasingFunction(ease); Vector3 newScale = easeFunc(startScale, endScale, percentage); transform.localScale = newScale; yield return null; if (ShouldStop(id)) { yield break; } } if (OnComplete != null) { OnComplete(); } } static IEnumerator ScaleComponentToCoroutine(int id, Transform transform, float endScale, VectorComponent component, float time, float delay, Ease ease, Action OnComplete, Loop loop, int numOfLoops, bool useRealTime) { if (delay > 0) { yield return new WaitForSeconds(delay); } float timeSoFar = 0; float percentage = 0; Vector3 start = transform.localScale; float startScale = 0; switch (component) { case VectorComponent.x: startScale = start.x; break; case VectorComponent.y: startScale = start.y; break; case VectorComponent.z: startScale = start.z; break; } bool reverse = false; bool playing = true; float lastRealTime = Time.realtimeSinceStartup; while (playing) { if (reverse) { timeSoFar -= GetDeltaTime(useRealTime, ref lastRealTime); percentage = timeSoFar / time; if (percentage < 0) { timeSoFar = 0; percentage = 0; reverse = false; --numOfLoops; if (numOfLoops == 0) { playing = false; } } } else { timeSoFar += GetDeltaTime(useRealTime, ref lastRealTime); percentage = timeSoFar / time; if (percentage > 1) { if (loop == Loop.loop) { --numOfLoops; if (numOfLoops > 0) { timeSoFar = 0; percentage = 0; } else { percentage = 1; playing = false; } } else if (loop == Loop.pingPong) { timeSoFar = time; percentage = 1; reverse = true; } else { percentage = 1; playing = false; } } } FloatEasingFunction easeFunc = GetFloatEasingFunction(ease); float newComponent = easeFunc(startScale, endScale, percentage); Vector3 newScale = transform.localScale; switch (component) { case VectorComponent.x: newScale.x = newComponent; break; case VectorComponent.y: newScale.y = newComponent; break; case VectorComponent.z: newScale.z = newComponent; break; } transform.localScale = newScale; yield return null; if (ShouldStop(id)) { yield break; } } if (OnComplete != null) { OnComplete(); } } #endregion #region Rotation public static int RotateTo(this MonoBehaviour mb, Quaternion rot, float time, float delay = 0, CoordinateSystem coordinateSystem = CoordinateSystem.Global, Ease ease = Ease.easeOutCubic, Action OnComplete = null, Loop loop = Loop.none, int numOfLoops = int.MaxValue, bool useRealTime = false) { mb.StartCoroutine(RotateToCoroutine(++_nextAnimationId, mb.transform, rot, time, delay, coordinateSystem, ease, OnComplete, loop, numOfLoops, useRealTime)); return _nextAnimationId; } static IEnumerator RotateToCoroutine(int id, Transform transform, Quaternion endRot, float time, float delay, CoordinateSystem coordinateSystem, Ease ease, Action OnComplete, Loop loop, int numOfLoops, bool useRealTime) { if (delay > 0) { yield return new WaitForSeconds(delay); } float timeSoFar = 0; float percentage = 0; Quaternion startRot = coordinateSystem == CoordinateSystem.Local ? transform.localRotation : transform.rotation; bool reverse = false; bool playing = true; float lastRealTime = Time.realtimeSinceStartup; while (playing) { if (reverse) { timeSoFar -= GetDeltaTime(useRealTime, ref lastRealTime); percentage = timeSoFar / time; if (percentage < 0) { timeSoFar = 0; percentage = 0; reverse = false; --numOfLoops; if (numOfLoops == 0) { playing = false; } } } else { timeSoFar += GetDeltaTime(useRealTime, ref lastRealTime); percentage = timeSoFar / time; if (percentage > 1) { if (loop == Loop.loop) { --numOfLoops; if (numOfLoops > 0) { timeSoFar = 0; percentage = 0; } else { percentage = 1; playing = false; } } else if (loop == Loop.pingPong) { timeSoFar = time; percentage = 1; reverse = true; } else { percentage = 1; playing = false; } } } FloatEasingFunction easeFunc = GetFloatEasingFunction(ease); float t = easeFunc(0, 1, percentage); Quaternion newRot = Quaternion.Slerp(startRot, endRot, t); if (coordinateSystem == CoordinateSystem.Local) { transform.localRotation = newRot; } else { transform.rotation = newRot; } yield return null; if (ShouldStop(id)) { yield break; } } if (OnComplete != null) { OnComplete(); } } #endregion #region Value public static int ValueTo(this MonoBehaviour mb, float from, float to, float time, Action OnUpdate, float delay = 0, Ease ease = Ease.linear, Action OnComplete = null, Loop loop = Loop.none, int numOfLoops = 0, bool useRealTime = false) { mb.StartCoroutine(ValueToCoroutine(++_nextAnimationId, from, to, time, OnUpdate, delay, ease, OnComplete, loop, numOfLoops, useRealTime)); return _nextAnimationId; } static IEnumerator ValueToCoroutine(int id, float from, float to, float time, Action OnUpdate, float delay, Ease ease, Action OnComplete, Loop loop, int numOfLoops, bool useRealTime) { if (delay > 0) { yield return new WaitForSeconds(delay); } float timeSoFar = 0; float percentage = 0; bool reverse = false; bool playing = true; float lastRealTime = Time.realtimeSinceStartup; while (playing) { if (reverse) { timeSoFar -= GetDeltaTime(useRealTime, ref lastRealTime); percentage = timeSoFar / time; if (percentage < 0) { timeSoFar = 0; percentage = 0; reverse = false; --numOfLoops; if (numOfLoops == 0) { playing = false; } } } else { timeSoFar += GetDeltaTime(useRealTime, ref lastRealTime); percentage = timeSoFar / time; if (percentage > 1) { if (loop == Loop.loop) { --numOfLoops; if (numOfLoops > 0) { percentage = 0; } else { percentage = 1; playing = false; } } else if (loop == Loop.pingPong) { timeSoFar = time; percentage = 1; reverse = true; } else { percentage = 1; playing = false; } } } FloatEasingFunction easeFunc = GetFloatEasingFunction(ease); float newValue = easeFunc(from, to, percentage); OnUpdate(newValue); yield return null; if (ShouldStop(id)) { yield break; } } if (OnComplete != null) { OnComplete(); } } #endregion #region Ease Mapping Functions private static FloatEasingFunction GetFloatEasingFunction(Ease ease) { switch (ease) { case Ease.easeInQuad: return FloatEaseInQuad; case Ease.easeOutQuad: return FloatEaseOutQuad; case Ease.easeInOutQuad: return FloatEaseInOutQuad; case Ease.easeInCubic: return FloatEaseInCubic; case Ease.easeOutCubic: return FloatEaseOutCubic; case Ease.easeInOutCubic: return FloatEaseInOutCubic; case Ease.easeInQuart: return FloatEaseInQuart; case Ease.easeOutQuart: return FloatEaseOutQuart; case Ease.easeInOutQuart: return FloatEaseInOutQuart; case Ease.easeInQuint: return FloatEaseInQuint; case Ease.easeOutQuint: return FloatEaseOutQuint; case Ease.easeInOutQuint: return FloatEaseInOutQuint; case Ease.easeInSine: return FloatEaseInSine; case Ease.easeOutSine: return FloatEaseOutSine; case Ease.easeInOutSine: return FloatEaseInOutSine; case Ease.easeInExpo: return FloatEaseInExpo; case Ease.easeOutExpo: return FloatEaseOutExpo; case Ease.easeInOutExpo: return FloatEaseInOutExpo; case Ease.easeInCirc: return FloatEaseInCirc; case Ease.easeOutCirc: return FloatEaseOutCirc; case Ease.easeInOutCirc: return FloatEaseInOutCirc; case Ease.linear: return FloatLinear; case Ease.spring: return FloatSpring; case Ease.easeInBounce: return FloatEaseInBounce; case Ease.easeOutBounce: return FloatEaseOutBounce; case Ease.easeInOutBounce: return FloatEaseInOutBounce; case Ease.easeInBack: return FloatEaseInBack; case Ease.easeOutBack: return FloatEaseOutBack; case Ease.easeInOutBack: return FloatEaseInOutBack; case Ease.easeInElastic: return FloatEaseInElastic; case Ease.easeOutElastic: return FloatEaseOutElastic; case Ease.easeInOutElastic: return FloatEaseInOutElastic; default: Debug.LogError("Float Easing Function " + ease + " not found"); return null; } } private static Vector3EasingFunction GetVector3EasingFunction(Ease ease) { switch (ease) { case Ease.easeInQuad: return Vector3EaseInQuad; case Ease.easeOutQuad: return Vector3EaseOutQuad; case Ease.easeInOutQuad: return Vector3EaseInOutQuad; case Ease.easeInCubic: return Vector3EaseInCubic; case Ease.easeOutCubic: return Vector3EaseOutCubic; case Ease.easeInOutCubic: return Vector3EaseInOutCubic; case Ease.easeInQuart: return Vector3EaseInQuart; case Ease.easeOutQuart: return Vector3EaseOutQuart; case Ease.easeInOutQuart: return Vector3EaseInOutQuart; case Ease.easeInQuint: return Vector3EaseInQuint; case Ease.easeOutQuint: return Vector3EaseOutQuint; case Ease.easeInOutQuint: return Vector3EaseInOutQuint; case Ease.easeInSine: return Vector3EaseInSine; case Ease.easeOutSine: return Vector3EaseOutSine; case Ease.easeInOutSine: return Vector3EaseInOutSine; case Ease.easeInExpo: return Vector3EaseInExpo; case Ease.easeOutExpo: return Vector3EaseOutExpo; case Ease.easeInOutExpo: return Vector3EaseInOutExpo; case Ease.easeInCirc: return Vector3EaseInCirc; case Ease.easeOutCirc: return Vector3EaseOutCirc; case Ease.easeInOutCirc: return Vector3EaseInOutCirc; case Ease.linear: return Vector3Linear; case Ease.spring: return Vector3Spring; case Ease.easeInBounce: return Vector3EaseInBounce; case Ease.easeOutBounce: return Vector3EaseOutBounce; case Ease.easeInOutBounce: return Vector3EaseInOutBounce; case Ease.easeInBack: return Vector3EaseInBack; case Ease.easeOutBack: return Vector3EaseOutBack; case Ease.easeInOutBack: return Vector3EaseInOutBack; case Ease.easeInElastic: return Vector3EaseInElastic; case Ease.easeOutElastic: return Vector3EaseOutElastic; case Ease.easeInOutElastic: return Vector3EaseInOutElastic; default: Debug.LogError("Vector3 Easing Function " + ease + " not found"); return null; } } #endregion #region Float easing functions private static float FloatLinear(float start, float end, float value) { return Mathf.Lerp(start, end, value); } private static float FloatSpring(float start, float end, float value) { value = Mathf.Clamp01(value); value = (Mathf.Sin(value * Mathf.PI * (0.2f + 2.5f * value * value * value)) * Mathf.Pow(1f - value, 2.2f) + value) * (1f + (1.2f * (1f - value))); return start + (end - start) * value; } private static float FloatEaseInQuad(float start, float end, float value) { end -= start; return end * value * value + start; } private static float FloatEaseOutQuad(float start, float end, float value) { end -= start; return -end * value * (value - 2) + start; } private static float FloatEaseInOutQuad(float start, float end, float value) { value /= .5f; end -= start; if (value < 1) { return end / 2 * value * value + start; } value--; return -end / 2 * (value * (value - 2) - 1) + start; } private static float FloatEaseInCubic(float start, float end, float value) { end -= start; return end * value * value * value + start; } private static float FloatEaseOutCubic(float start, float end, float value) { value--; end -= start; return end * (value * value * value + 1) + start; } private static float FloatEaseInOutCubic(float start, float end, float value) { value /= .5f; end -= start; if (value < 1) { return end / 2 * value * value * value + start; } value -= 2; return end / 2 * (value * value * value + 2) + start; } private static float FloatEaseInQuart(float start, float end, float value) { end -= start; return end * value * value * value * value + start; } private static float FloatEaseOutQuart(float start, float end, float value) { value--; end -= start; return -end * (value * value * value * value - 1) + start; } private static float FloatEaseInOutQuart(float start, float end, float value) { value /= .5f; end -= start; if (value < 1) { return end / 2 * value * value * value * value + start; } value -= 2; return -end / 2 * (value * value * value * value - 2) + start; } private static float FloatEaseInQuint(float start, float end, float value) { end -= start; return end * value * value * value * value * value + start; } private static float FloatEaseOutQuint(float start, float end, float value) { value--; end -= start; return end * (value * value * value * value * value + 1) + start; } private static float FloatEaseInOutQuint(float start, float end, float value) { value /= .5f; end -= start; if (value < 1) { return end / 2 * value * value * value * value * value + start; } value -= 2; return end / 2 * (value * value * value * value * value + 2) + start; } private static float FloatEaseInSine(float start, float end, float value) { end -= start; return -end * Mathf.Cos(value / 1 * (Mathf.PI / 2)) + end + start; } private static float FloatEaseOutSine(float start, float end, float value) { end -= start; return end * Mathf.Sin(value / 1 * (Mathf.PI / 2)) + start; } private static float FloatEaseInOutSine(float start, float end, float value) { end -= start; return -end / 2 * (Mathf.Cos(Mathf.PI * value / 1) - 1) + start; } private static float FloatEaseInExpo(float start, float end, float value) { end -= start; return end * Mathf.Pow(2, 10 * (value / 1 - 1)) + start; } private static float FloatEaseOutExpo(float start, float end, float value) { end -= start; return end * (-Mathf.Pow(2, -10 * value / 1) + 1) + start; } private static float FloatEaseInOutExpo(float start, float end, float value) { value /= .5f; end -= start; if (value < 1) { return end / 2 * Mathf.Pow(2, 10 * (value - 1)) + start; } value--; return end / 2 * (-Mathf.Pow(2, -10 * value) + 2) + start; } private static float FloatEaseInCirc(float start, float end, float value) { end -= start; return -end * (Mathf.Sqrt(1 - value * value) - 1) + start; } private static float FloatEaseOutCirc(float start, float end, float value) { value--; end -= start; return end * Mathf.Sqrt(1 - value * value) + start; } private static float FloatEaseInOutCirc(float start, float end, float value) { value /= .5f; end -= start; if (value < 1) { return -end / 2 * (Mathf.Sqrt(1 - value * value) - 1) + start; } value -= 2; return end / 2 * (Mathf.Sqrt(1 - value * value) + 1) + start; } private static float FloatEaseInBounce(float start, float end, float value) { end -= start; float d = 1f; return end - FloatEaseOutBounce(0, end, d - value) + start; } private static float FloatEaseOutBounce(float start, float end, float value) { value /= 1f; end -= start; if (value < (1 / 2.75f)) { return end * (7.5625f * value * value) + start; } else if (value < (2 / 2.75f)) { value -= (1.5f / 2.75f); return end * (7.5625f * (value) * value + .75f) + start; } else if (value < (2.5 / 2.75)) { value -= (2.25f / 2.75f); return end * (7.5625f * (value) * value + .9375f) + start; } else { value -= (2.625f / 2.75f); return end * (7.5625f * (value) * value + .984375f) + start; } } private static float FloatEaseInOutBounce(float start, float end, float value) { end -= start; float d = 1f; if (value < d / 2) { return FloatEaseInBounce(0, end, value * 2) * 0.5f + start; } else { return FloatEaseOutBounce(0, end, value * 2 - d) * 0.5f + end * 0.5f + start; } } private static float FloatEaseInBack(float start, float end, float value) { end -= start; value /= 1; float s = 1.70158f; return end * (value) * value * ((s + 1) * value - s) + start; } private static float FloatEaseOutBack(float start, float end, float value) { float s = 1.70158f; end -= start; value = (value / 1) - 1; return end * ((value) * value * ((s + 1) * value + s) + 1) + start; } private static float FloatEaseInOutBack(float start, float end, float value) { float s = 1.70158f; end -= start; value /= .5f; if ((value) < 1) { s *= (1.525f); return end / 2 * (value * value * (((s) + 1) * value - s)) + start; } value -= 2; s *= (1.525f); return end / 2 * ((value) * value * (((s) + 1) * value + s) + 2) + start; } private static float FloatEaseInElastic(float start, float end, float value) { end -= start; float d = 1f; float p = d * .3f; float s = 0; 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; } else { s = p / (2 * Mathf.PI) * Mathf.Asin(end / a); } return -(a * Mathf.Pow(2, 10 * (value -= 1)) * Mathf.Sin((value * d - s) * (2 * Mathf.PI) / p)) + start; } private static float FloatEaseOutElastic(float start, float end, float value) { end -= start; float d = 1f; float p = d * .3f; float s = 0; 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; } else { s = p / (2 * Mathf.PI) * Mathf.Asin(end / a); } return (a * Mathf.Pow(2, -10 * value) * Mathf.Sin((value * d - s) * (2 * Mathf.PI) / p) + end + start); } private static float FloatEaseInOutElastic(float start, float end, float value) { end -= start; float d = 1f; float p = d * .3f; float s = 0; float a = 0; if (value == 0) { return start; } if ((value /= d / 2) == 2) { return start + end; } if (a == 0f || a < Mathf.Abs(end)) { a = end; s = p / 4; } 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 * (value -= 1)) * Mathf.Sin((value * d - s) * (2 * Mathf.PI) / p) * 0.5f + end + start; } #endregion #region Vector3 easing functions private static Vector3 Vector3Linear(Vector3 start, Vector3 end, float value) { return Vector3.Lerp(start, end, value); } private static Vector3 Vector3Spring(Vector3 start, Vector3 end, float value){ value = Mathf.Clamp01(value); value = (Mathf.Sin(value * Mathf.PI * (0.2f + 2.5f * value * value * value)) * Mathf.Pow(1f - value, 2.2f) + value) * (1f + (1.2f * (1f - value))); return start + (end - start) * value; } private static Vector3 Vector3EaseInQuad(Vector3 start, Vector3 end, float value) { end -= start; return end * value * value + start; } private static Vector3 Vector3EaseOutQuad(Vector3 start, Vector3 end, float value) { end -= start; return -end * value * (value - 2) + start; } private static Vector3 Vector3EaseInOutQuad(Vector3 start, Vector3 end, float value) { value /= .5f; end -= start; if (value < 1) { return end / 2 * value * value + start; } value--; return -end / 2 * (value * (value - 2) - 1) + start; } private static Vector3 Vector3EaseInCubic(Vector3 start, Vector3 end, float value) { end -= start; return end * value * value * value + start; } private static Vector3 Vector3EaseOutCubic(Vector3 start, Vector3 end, float value) { value--; end -= start; return end * (value * value * value + 1) + start; } private static Vector3 Vector3EaseInOutCubic(Vector3 start, Vector3 end, float value) { value /= .5f; end -= start; if (value < 1) { return end / 2 * value * value * value + start; } value -= 2; return end / 2 * (value * value * value + 2) + start; } private static Vector3 Vector3EaseInQuart(Vector3 start, Vector3 end, float value) { end -= start; return end * value * value * value * value + start; } private static Vector3 Vector3EaseOutQuart(Vector3 start, Vector3 end, float value) { value--; end -= start; return -end * (value * value * value * value - 1) + start; } private static Vector3 Vector3EaseInOutQuart(Vector3 start, Vector3 end, float value) { value /= .5f; end -= start; if (value < 1) { return end / 2 * value * value * value * value + start; } value -= 2; return -end / 2 * (value * value * value * value - 2) + start; } private static Vector3 Vector3EaseInQuint(Vector3 start, Vector3 end, float value) { end -= start; return end * value * value * value * value * value + start; } private static Vector3 Vector3EaseOutQuint(Vector3 start, Vector3 end, float value) { value--; end -= start; return end * (value * value * value * value * value + 1) + start; } private static Vector3 Vector3EaseInOutQuint(Vector3 start, Vector3 end, float value) { value /= .5f; end -= start; if (value < 1) { return end / 2 * value * value * value * value * value + start; } value -= 2; return end / 2 * (value * value * value * value * value + 2) + start; } private static Vector3 Vector3EaseInSine(Vector3 start, Vector3 end, float value) { end -= start; return -end * Mathf.Cos(value / 1 * (Mathf.PI / 2)) + end + start; } private static Vector3 Vector3EaseOutSine(Vector3 start, Vector3 end, float value) { end -= start; return end * Mathf.Sin(value / 1 * (Mathf.PI / 2)) + start; } private static Vector3 Vector3EaseInOutSine(Vector3 start, Vector3 end, float value) { end -= start; return -end / 2 * (Mathf.Cos(Mathf.PI * value / 1) - 1) + start; } private static Vector3 Vector3EaseInExpo(Vector3 start, Vector3 end, float value) { end -= start; return end * Mathf.Pow(2, 10 * (value / 1 - 1)) + start; } private static Vector3 Vector3EaseOutExpo(Vector3 start, Vector3 end, float value) { end -= start; return end * (-Mathf.Pow(2, -10 * value / 1) + 1) + start; } private static Vector3 Vector3EaseInOutExpo(Vector3 start, Vector3 end, float value) { value /= .5f; end -= start; if (value < 1) { return end / 2 * Mathf.Pow(2, 10 * (value - 1)) + start; } value--; return end / 2 * (-Mathf.Pow(2, -10 * value) + 2) + start; } private static Vector3 Vector3EaseInCirc(Vector3 start, Vector3 end, float value) { end -= start; return -end * (Mathf.Sqrt(1 - value * value) - 1) + start; } private static Vector3 Vector3EaseOutCirc(Vector3 start, Vector3 end, float value) { value--; end -= start; return end * Mathf.Sqrt(1 - value * value) + start; } private static Vector3 Vector3EaseInOutCirc(Vector3 start, Vector3 end, float value) { value /= .5f; end -= start; if (value < 1) { return -end / 2 * (Mathf.Sqrt(1 - value * value) - 1) + start; } value -= 2; return end / 2 * (Mathf.Sqrt(1 - value * value) + 1) + start; } private static Vector3 Vector3EaseInBounce(Vector3 start, Vector3 end, float value) { end -= start; float d = 1f; return end - Vector3EaseOutBounce(Vector3.zero, end, d - value) + start; } private static Vector3 Vector3EaseOutBounce(Vector3 start, Vector3 end, float value) { value /= 1f; end -= start; if (value < (1 / 2.75f)) { return end * (7.5625f * value * value) + start; } else if (value < (2 / 2.75f)) { value -= (1.5f / 2.75f); return end * (7.5625f * (value) * value + .75f) + start; } else if (value < (2.5 / 2.75)) { value -= (2.25f / 2.75f); return end * (7.5625f * (value) * value + .9375f) + start; } else { value -= (2.625f / 2.75f); return end * (7.5625f * (value) * value + .984375f) + start; } } private static Vector3 Vector3EaseInOutBounce(Vector3 start, Vector3 end, float value) { end -= start; float d = 1f; if (value < d / 2) { return Vector3EaseInBounce(Vector3.zero, end, value * 2) * 0.5f + start; } else { return Vector3EaseOutBounce(Vector3.zero, end, value * 2 - d) * 0.5f + end * 0.5f + start; } } private static Vector3 Vector3EaseInBack(Vector3 start, Vector3 end, float value) { end -= start; value /= 1; float s = 1.70158f; return end * (value) * value * ((s + 1) * value - s) + start; } private static Vector3 Vector3EaseOutBack(Vector3 start, Vector3 end, float value) { float s = 1.70158f; end -= start; value = (value / 1) - 1; return end * ((value) * value * ((s + 1) * value + s) + 1) + start; } private static Vector3 Vector3EaseInOutBack(Vector3 start, Vector3 end, float value) { float s = 1.70158f; end -= start; value /= .5f; if ((value) < 1) { s *= (1.525f); return end / 2 * (value * value * (((s) + 1) * value - s)) + start; } value -= 2; s *= (1.525f); return end / 2 * ((value) * value * (((s) + 1) * value + s) + 2) + start; } private static Vector3 Vector3EaseInElastic(Vector3 start, Vector3 end, float value) { return new Vector3( FloatEaseInElastic(start.x, end.x, value), FloatEaseInElastic(start.y, end.y, value), FloatEaseInElastic(start.z, end.z, value)); } private static Vector3 Vector3EaseOutElastic(Vector3 start, Vector3 end, float value) { return new Vector3( FloatEaseOutElastic(start.x, end.x, value), FloatEaseOutElastic(start.y, end.y, value), FloatEaseOutElastic(start.z, end.z, value)); } private static Vector3 Vector3EaseInOutElastic(Vector3 start, Vector3 end, float value) { return new Vector3( FloatEaseInOutElastic(start.x, end.x, value), FloatEaseInOutElastic(start.y, end.y, value), FloatEaseInOutElastic(start.z, end.z, value)); } #endregion }