| //-------------------------------------------------------- | 
| //    [Author]:           第二世界 | 
| //    [  Date ]:           Thursday, September 14, 2017 | 
| //-------------------------------------------------------- | 
| using UnityEngine; | 
| using System.Collections; | 
| using UnityEngine.UI; | 
| using System; | 
|   | 
|      | 
|     [RequireComponent(typeof(CanvasGroup))] | 
|     public class UIAlphaTween : MonoBehaviour | 
|     { | 
|         public TweenCurve curve; | 
|         [Range(0, 1)] | 
|         public float from; | 
|         [Range(0, 1)] | 
|         public float to; | 
|         public float delay = 0f; | 
|         public float duration = 1f; | 
|         public Trigger trigger = Trigger.Manual; | 
|         public WrapMode wrapMode; | 
|         public bool reversal; | 
|   | 
|         CanvasGroup m_CanvasGroup; | 
|         public CanvasGroup canvasGroup { | 
|             get { | 
|                 return m_CanvasGroup ?? (m_CanvasGroup = this.GetComponent<CanvasGroup>()); | 
|             } | 
|         } | 
|   | 
|         protected float accumulatedTime; | 
|         protected float curveLength; | 
|         protected bool doTween = false; | 
|   | 
|         Action onPlayEndCallBack; | 
|   | 
|         public void SetStartState() | 
|         { | 
|             canvasGroup.alpha = from; | 
|         } | 
|   | 
|         public void SetEndState() | 
|         { | 
|             canvasGroup.alpha = to; | 
|         } | 
|   | 
|         public void Play() | 
|         { | 
|             onPlayEndCallBack = null; | 
|             reversal = false; | 
|             StopAllCoroutines(); | 
|             if (this.gameObject.activeInHierarchy) | 
|             { | 
|                 SetStartState(); | 
|                 StartCoroutine("Co_StartTween"); | 
|             } | 
|         } | 
|   | 
|         public void Play(bool _reversal) | 
|         { | 
|             onPlayEndCallBack = null; | 
|             reversal = _reversal; | 
|             StopAllCoroutines(); | 
|             if (this.gameObject.activeInHierarchy) | 
|             { | 
|                 if (_reversal) | 
|                 { | 
|                     SetEndState(); | 
|                 } | 
|                 else | 
|                 { | 
|                     SetStartState(); | 
|                 } | 
|   | 
|                 StartCoroutine("Co_StartTween"); | 
|             } | 
|         } | 
|   | 
|         public void Play(Action _callBack) | 
|         { | 
|             onPlayEndCallBack = _callBack; | 
|             reversal = false; | 
|             StopAllCoroutines(); | 
|             if (this.gameObject.activeInHierarchy) | 
|             { | 
|                 SetStartState(); | 
|                 StartCoroutine("Co_StartTween"); | 
|             } | 
|         } | 
|   | 
|         public void Stop() | 
|         { | 
|             doTween = false; | 
|             accumulatedTime = 0f; | 
|             StopAllCoroutines(); | 
|             SetStartState(); | 
|         } | 
|   | 
|   | 
|         void Start() | 
|         { | 
|             if (trigger == Trigger.Start) | 
|             { | 
|                 SetStartState(); | 
|                 StartCoroutine("Co_StartTween"); | 
|             } | 
|         } | 
|   | 
|         protected virtual void OnEnable() | 
|         { | 
|             if (trigger == Trigger.Enable) | 
|             { | 
|                 SetStartState(); | 
|                 StartCoroutine("Co_StartTween"); | 
|             } | 
|         } | 
|   | 
|         protected virtual void OnDisable() | 
|         { | 
|             doTween = false; | 
|             accumulatedTime = 0f; | 
|             StopAllCoroutines(); | 
|         } | 
|   | 
|         void LateUpdate() | 
|         { | 
|             if (doTween && duration > 0.001f) | 
|             { | 
|                 accumulatedTime += Time.deltaTime; | 
|                 UpdateAlpha(); | 
|             } | 
|         } | 
|   | 
|         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; | 
|             } | 
|   | 
|             doTween = false; | 
|             OnPrepare(); | 
|             yield return new WaitForSeconds(delay); | 
|             curveLength = curve.keys[curve.keys.Length - 1].time - curve.keys[0].time; | 
|             doTween = true; | 
|             accumulatedTime = 0f; | 
|         } | 
|   | 
|         protected void UpdateAlpha() | 
|         { | 
|             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; | 
|             } | 
|   | 
|             var value = curve.Evaluate(reversal ? curveLength - t : t); | 
|             canvasGroup.alpha = Mathf.LerpUnclamped(from, to, value); | 
|   | 
|             switch (wrapMode) | 
|             { | 
|                 case WrapMode.Once: | 
|                     if (t > curveLength && doTween) | 
|                     { | 
|                         OnOnceEnd(); | 
|                         doTween = false; | 
|                     } | 
|                     break; | 
|             } | 
|         } | 
|   | 
|         protected virtual void OnPrepare() | 
|         { | 
|   | 
|         } | 
|   | 
|         protected virtual void OnOnceEnd() | 
|         { | 
|             if (onPlayEndCallBack != null) | 
|             { | 
|                 onPlayEndCallBack(); | 
|                 onPlayEndCallBack = null; | 
|             } | 
|         } | 
|   | 
|         protected virtual void UpdateVector3() | 
|         { | 
|   | 
|         } | 
|   | 
|         public enum Trigger | 
|         { | 
|             Manual, | 
|             Start, | 
|             Enable, | 
|         } | 
|   | 
|         public enum WrapMode | 
|         { | 
|             Once, | 
|             Loop, | 
|             PingPong, | 
|         } | 
|   | 
|     } |