using UnityEngine; using System.Collections.Generic; using System.Linq; using System.Collections; using System; using UnityEngine.Events; /// /// Play the specified tween on click. /// [ExecuteInEditMode, DefaultExecutionOrder(-100)] public sealed class PlayTween : MonoBehaviour { /// /// Target on which there is one or more tween. /// public GameObject tweenTarget; /// /// If there are multiple tweens, you can choose which ones get activated by changing their group. /// public int tweenGroup = 0; /// /// How long will the tweener wait before starting the tween? /// public float delay = 0f; /// /// Direction to tween in. /// public Direction playDirection = Direction.Forward; /// /// Whether the tween will be reset to the start or end when activated. If not, it will continue from where it currently is. /// public bool resetOnPlay = false; /// /// Whether the tween will be reset to the start if it's disabled when activated. /// public bool resetIfDisabled = false; /// /// What to do if the tweenTarget game object is currently disabled. /// public EnableCondition ifDisabledOnPlay = EnableCondition.DoNothing; /// /// What to do with the tweenTarget after the tween finishes. /// public DisableCondition disableWhenFinished = DisableCondition.DoNotDisable; /// /// Whether the tweens on the child game objects will be considered. /// public bool includeChildren = false; [SerializeField] UnityEvent m_OnBeginning = new UnityEvent(); [SerializeField] UnityEvent m_OnFinished = new UnityEvent(); /// /// 开始前执行 /// public event Action onBeginning; /// /// 完毕后执行 /// public event Action onFinished; Tweener[] mTweens; int mActive = 0; /// /// 正向 /// public void PlayForward() { Play(true); } /// /// 反向 /// public void PlayReverse() { Play(false); } void Awake() { onBeginning += m_OnBeginning.Invoke; onFinished += m_OnFinished.Invoke; if (tweenTarget == null) tweenTarget = gameObject; } /// /// Activate the tweeners. /// public void Play(bool forward) { if (onBeginning != null) onBeginning(); mActive = 0; GameObject go = (tweenTarget == null) ? gameObject : tweenTarget; if (!go.activeSelf) { // If the object is disabled, don't do anything if (ifDisabledOnPlay != EnableCondition.EnableThenPlay) return; // Enable the game object before tweening it go.SetActive(true); } // Gather the tweening components mTweens = includeChildren ? go.GetComponentsInChildren() : go.GetComponents(); if (mTweens.Length == 0) { // No tweeners found -- should we disable the object? if (disableWhenFinished != DisableCondition.DoNotDisable) tweenTarget.SetActive(true); } else { bool activated = false; if (playDirection == Direction.Reverse) forward = !forward; // Run through all located tween components Tweener maxDurTW = null; for (int i = 0, imax = mTweens.Length; i < imax; ++i) { Tweener tw = mTweens[i]; tw.onFinished = null; // If the tweener's group matches, we can work with it if (tw.tweenGroup == tweenGroup) { // Ensure that the game objects are enabled if (!activated && !go.activeSelf) { activated = true; go.SetActive(true); } ++mActive; // Toggle or activate the tween component if (playDirection == Direction.Toggle) { tw.Toggle(); } else { if (resetOnPlay || (resetIfDisabled && !tw.enabled)) tw.ResetToBeginning(); tw.Play(forward); } if (maxDurTW == null) { maxDurTW = tw; } else { if (maxDurTW.delay + maxDurTW.duration < tw.delay + tw.duration) maxDurTW = tw; } } } maxDurTW.onFinished = () => { if (onFinished != null) onFinished(); if (disableWhenFinished != DisableCondition.DoNotDisable && (int)maxDurTW.direction == (int)disableWhenFinished) { tweenTarget.SetActive(false); } else { tweenTarget.SetActive(true); } }; } } }