using UnityEngine; using System.Collections; using System; [RequireComponent(typeof(RectTransform))] public class TweenEx : MonoBehaviour { public TweenCurve curve; public Vector3 from; public Vector3 to; public DelayMode delayMode = DelayMode.Time; public float delay = 0f; public float duration = 1f; public Trigger trigger = Trigger.Manual; public WrapMode wrapMode; public bool reversal; protected RectTransform rectTransform { get { return this.transform as RectTransform; } } protected float accumulatedTime; protected float curveLength; protected bool doTween = false; Action onPlayEndCallBack; public virtual void SetStartState() { } public virtual void SetEndState() { } public void Play() { onPlayEndCallBack = null; reversal = false; StopAllCoroutines(); StartCoroutine(Co_StartTween()); } public void Play(bool _reversal) { onPlayEndCallBack = null; reversal = _reversal; StopAllCoroutines(); StartCoroutine(Co_StartTween()); } public void Play(Action _callBack) { reversal = false; onPlayEndCallBack = _callBack; StopAllCoroutines(); StartCoroutine(Co_StartTween()); } public void Play(bool _reversal, Action _callBack) { reversal = _reversal; onPlayEndCallBack = _callBack; StopAllCoroutines(); StartCoroutine(Co_StartTween()); } void Start() { if (trigger == Trigger.Start) { StartCoroutine(Co_StartTween()); } } protected virtual void OnEnable() { if (trigger == Trigger.Enable) { StartCoroutine(Co_StartTween()); } } protected virtual void OnDisable() { onPlayEndCallBack = null; StopAllCoroutines(); } void LateUpdate() { if (doTween && duration > 0.001f) { accumulatedTime += Time.deltaTime; UpdateVector3(); switch (wrapMode) { case WrapMode.Once: case WrapMode.PingPongOnce: if (accumulatedTime > duration) { OnOnceEnd(); doTween = false; } break; } } } IEnumerator Co_StartTween() { if (delay < 0f) { Debug.LogError("Delaytime should not be less than zero!"); yield break; } if (duration < 0.001f) { Debug.LogError("Duration should not be less than zero!"); yield break; } if (curve.keys.Length < 2) { Debug.LogError("不正确的曲线!"); yield break; } accumulatedTime = 0f; doTween = false; OnPrepare(); switch (delayMode) { case DelayMode.OneFrame: yield return null; break; case DelayMode.TwiceFrame: yield return null; yield return null; break; case DelayMode.Time: if (delay > 0.001f) { yield return new WaitForSeconds(delay); } break; } curveLength = curve.keys[curve.keys.Length - 1].time - curve.keys[0].time; doTween = true; } protected Vector3 CalculateVector3() { Vector3 newVector3 = Vector3.zero; float t = 0f; switch (wrapMode) { case WrapMode.Once: t = (accumulatedTime / duration) * curveLength; break; case WrapMode.Loop: t = Mathf.Repeat((accumulatedTime / duration) * curveLength, 1); break; case WrapMode.PingPong: t = Mathf.PingPong((accumulatedTime / duration) * curveLength, 1); break; case WrapMode.PingPongOnce: t = Mathf.PingPong((accumulatedTime / (duration/2)) * curveLength, 1); break; } var value = curve.Evaluate(reversal ? curveLength - t : t); newVector3 = Vector3.LerpUnclamped(from, to, value); return newVector3; } protected virtual void OnPrepare() { } protected virtual void OnOnceEnd() { if (onPlayEndCallBack != null) { onPlayEndCallBack(); onPlayEndCallBack = null; } } protected virtual void UpdateVector3() { } public void Stop() { doTween = false; } public void Resume() { doTween = true; } public enum DelayMode { OneFrame, TwiceFrame, Time, } public enum Trigger { Manual, Start, Enable, } public enum WrapMode { Once, Loop, PingPong, PingPongOnce, } }