PlayTween.cs 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200
  1. 
  2. using UnityEngine;
  3. using System.Collections.Generic;
  4. using System.Linq;
  5. using System.Collections;
  6. using System;
  7. using UnityEngine.Events;
  8. /// <summary>
  9. /// Play the specified tween on click.
  10. /// </summary>
  11. [ExecuteInEditMode, DefaultExecutionOrder(-100)]
  12. public sealed class PlayTween : MonoBehaviour
  13. {
  14. /// <summary>
  15. /// Target on which there is one or more tween.
  16. /// </summary>
  17. public GameObject tweenTarget;
  18. /// <summary>
  19. /// If there are multiple tweens, you can choose which ones get activated by changing their group.
  20. /// </summary>
  21. public int tweenGroup = 0;
  22. /// <summary>
  23. /// How long will the tweener wait before starting the tween?
  24. /// </summary>
  25. public float delay = 0f;
  26. /// <summary>
  27. /// Direction to tween in.
  28. /// </summary>
  29. public Direction playDirection = Direction.Forward;
  30. /// <summary>
  31. /// Whether the tween will be reset to the start or end when activated. If not, it will continue from where it currently is.
  32. /// </summary>
  33. public bool resetOnPlay = false;
  34. /// <summary>
  35. /// Whether the tween will be reset to the start if it's disabled when activated.
  36. /// </summary>
  37. public bool resetIfDisabled = false;
  38. /// <summary>
  39. /// What to do if the tweenTarget game object is currently disabled.
  40. /// </summary>
  41. public EnableCondition ifDisabledOnPlay = EnableCondition.DoNothing;
  42. /// <summary>
  43. /// What to do with the tweenTarget after the tween finishes.
  44. /// </summary>
  45. public DisableCondition disableWhenFinished = DisableCondition.DoNotDisable;
  46. /// <summary>
  47. /// Whether the tweens on the child game objects will be considered.
  48. /// </summary>
  49. public bool includeChildren = false;
  50. [SerializeField]
  51. UnityEvent m_OnBeginning = new UnityEvent();
  52. [SerializeField]
  53. UnityEvent m_OnFinished = new UnityEvent();
  54. /// <summary>
  55. /// 开始前执行
  56. /// </summary>
  57. public event Action onBeginning;
  58. /// <summary>
  59. /// 完毕后执行
  60. /// </summary>
  61. public event Action onFinished;
  62. Tweener[] mTweens;
  63. int mActive = 0;
  64. /// <summary>
  65. /// 正向
  66. /// </summary>
  67. public void PlayForward()
  68. {
  69. Play(true);
  70. }
  71. /// <summary>
  72. /// 反向
  73. /// </summary>
  74. public void PlayReverse()
  75. {
  76. Play(false);
  77. }
  78. void Awake()
  79. {
  80. onBeginning += m_OnBeginning.Invoke;
  81. onFinished += m_OnFinished.Invoke;
  82. if (tweenTarget == null)
  83. tweenTarget = gameObject;
  84. }
  85. /// <summary>
  86. /// Activate the tweeners.
  87. /// </summary>
  88. public void Play(bool forward)
  89. {
  90. if (onBeginning != null)
  91. onBeginning();
  92. mActive = 0;
  93. GameObject go = (tweenTarget == null) ? gameObject : tweenTarget;
  94. if (!go.activeSelf)
  95. {
  96. // If the object is disabled, don't do anything
  97. if (ifDisabledOnPlay != EnableCondition.EnableThenPlay)
  98. return;
  99. // Enable the game object before tweening it
  100. go.SetActive(true);
  101. }
  102. // Gather the tweening components
  103. mTweens = includeChildren ? go.GetComponentsInChildren<Tweener>() : go.GetComponents<Tweener>();
  104. if (mTweens.Length == 0)
  105. {
  106. // No tweeners found -- should we disable the object?
  107. if (disableWhenFinished != DisableCondition.DoNotDisable)
  108. tweenTarget.SetActive(true);
  109. }
  110. else
  111. {
  112. bool activated = false;
  113. if (playDirection == Direction.Reverse)
  114. forward = !forward;
  115. // Run through all located tween components
  116. Tweener maxDurTW = null;
  117. for (int i = 0, imax = mTweens.Length; i < imax; ++i)
  118. {
  119. Tweener tw = mTweens[i];
  120. tw.onFinished = null;
  121. // If the tweener's group matches, we can work with it
  122. if (tw.tweenGroup == tweenGroup)
  123. {
  124. // Ensure that the game objects are enabled
  125. if (!activated && !go.activeSelf)
  126. {
  127. activated = true;
  128. go.SetActive(true);
  129. }
  130. ++mActive;
  131. // Toggle or activate the tween component
  132. if (playDirection == Direction.Toggle)
  133. {
  134. tw.Toggle();
  135. }
  136. else
  137. {
  138. if (resetOnPlay || (resetIfDisabled && !tw.enabled))
  139. tw.ResetToBeginning();
  140. tw.Play(forward);
  141. }
  142. if (maxDurTW == null)
  143. {
  144. maxDurTW = tw;
  145. }
  146. else
  147. {
  148. if (maxDurTW.delay + maxDurTW.duration < tw.delay + tw.duration)
  149. maxDurTW = tw;
  150. }
  151. }
  152. }
  153. maxDurTW.onFinished = () =>
  154. {
  155. if (onFinished != null)
  156. onFinished();
  157. if (disableWhenFinished != DisableCondition.DoNotDisable && (int)maxDurTW.direction == (int)disableWhenFinished)
  158. {
  159. tweenTarget.SetActive(false);
  160. }
  161. else
  162. {
  163. tweenTarget.SetActive(true);
  164. }
  165. };
  166. }
  167. }
  168. }