hch
2025-09-08 14a9dc8c9b83dd7627f8ed99a163ebc41c1f9b8e
Main/Component/UI/Decorate/Tweens/UIAlphaTween.cs
@@ -7,222 +7,237 @@
using UnityEngine.UI;
using System;
    [RequireComponent(typeof(CanvasGroup))]
    public class UIAlphaTween : MonoBehaviour
[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()
    {
        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.alpha = from;
    }
        CanvasGroup m_CanvasGroup;
        public CanvasGroup canvasGroup {
            get {
                return m_CanvasGroup ?? (m_CanvasGroup = this.GetComponent<CanvasGroup>());
            }
        }
    public void SetEndState()
    {
        canvasGroup.alpha = to;
    }
        protected float accumulatedTime;
        protected float curveLength;
        protected bool doTween = false;
        Action onPlayEndCallBack;
        public void SetStartState()
    public void Play()
    {
        onPlayEndCallBack = null;
        reversal = false;
        StopAllCoroutines();
        if (this.gameObject.activeInHierarchy)
        {
            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();
            StartCoroutine("Co_StartTween");
        }
    }
        void Start()
    public void Play(bool _reversal)
    {
        onPlayEndCallBack = null;
        reversal = _reversal;
        StopAllCoroutines();
        if (this.gameObject.activeInHierarchy)
        {
            if (trigger == Trigger.Start)
            if (_reversal)
            {
                SetEndState();
            }
            else
            {
                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;
            StartCoroutine("Co_StartTween");
        }
    }
        protected void UpdateAlpha()
    public void Play(Action _callBack)
    {
        onPlayEndCallBack = _callBack;
        reversal = false;
        StopAllCoroutines();
        if (this.gameObject.activeInHierarchy)
        {
            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;
            }
            SetStartState();
            StartCoroutine("Co_StartTween");
        }
    }
        protected virtual void OnPrepare()
    public void Stop()
    {
        doTween = false;
        accumulatedTime = 0f;
        StopAllCoroutines();
        SetStartState();
    }
    void Start()
    {
        if (trigger == Trigger.Start)
        {
            SetStartState();
            StartCoroutine("Co_StartTween");
        }
    }
        protected virtual void OnOnceEnd()
    protected virtual void OnEnable()
    {
        if (trigger == Trigger.Enable)
        {
            if (onPlayEndCallBack != null)
            {
                onPlayEndCallBack();
                onPlayEndCallBack = null;
            }
            SetStartState();
            StartCoroutine("Co_StartTween");
        }
    }
        protected virtual void UpdateVector3()
    protected virtual void OnDisable()
    {
        doTween = false;
        accumulatedTime = 0f;
        StopAllCoroutines();
    }
    void LateUpdate()
    {
        if (doTween && duration > 0.001f)
        {
            accumulatedTime += Time.deltaTime;
            UpdateAlpha();
        }
    }
        public enum Trigger
    IEnumerator Co_StartTween()
    {
        if (delay < 0f)
        {
            Manual,
            Start,
            Enable,
            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;
        }
        public enum WrapMode
        if (curve.keys.Length < 2)
        {
            Once,
            Loop,
            PingPong,
            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;
            case WrapMode.PingPongOnce:
                t = Mathf.PingPong((accumulatedTime / (duration/2)) * curveLength, 1);
                break;
        }
        var value = curve.Evaluate(reversal ? curveLength - t : t);
        canvasGroup.alpha = Mathf.LerpUnclamped(from, to, value);
        switch (wrapMode)
        {
            case WrapMode.Once:
            case WrapMode.PingPongOnce:
                if (accumulatedTime > duration && doTween)
                {
                    OnOnceEnd();
                    doTween = false;
                }
                break;
        }
    }
    protected virtual void OnPrepare()
    {
    }
    protected virtual void OnOnceEnd()
    {
        if (wrapMode == WrapMode.PingPongOnce)
        {
            SetStartState();
        }
        else
        {
            canvasGroup.alpha = reversal ? from : to;
        }
        if (onPlayEndCallBack != null)
        {
            onPlayEndCallBack();
            onPlayEndCallBack = null;
        }
    }
    protected virtual void UpdateVector3()
    {
    }
    public enum Trigger
    {
        Manual,
        Start,
        Enable,
    }
    public enum WrapMode
    {
        Once,
        Loop,
        PingPong,
        PingPongOnce,
    }
}