CoroutineTween.cs 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244
  1. using System.Collections;
  2. using UnityEngine.Events;
  3. namespace UnityEngine.UI.CoroutineTween
  4. {
  5. // Base interface for tweeners,
  6. // using an interface instead of
  7. // an abstract class as we want the
  8. // tweens to be structs.
  9. internal interface ITweenValue
  10. {
  11. void TweenValue(float floatPercentage);
  12. bool ignoreTimeScale { get; }
  13. float duration { get; }
  14. bool ValidTarget();
  15. }
  16. // Color tween class, receives the
  17. // TweenValue callback and then sets
  18. // the value on the target.
  19. internal struct ColorTween : ITweenValue
  20. {
  21. public enum ColorTweenMode
  22. {
  23. All,
  24. RGB,
  25. Alpha
  26. }
  27. public class ColorTweenCallback : UnityEvent<Color> {}
  28. private ColorTweenCallback m_Target;
  29. private Color m_StartColor;
  30. private Color m_TargetColor;
  31. private ColorTweenMode m_TweenMode;
  32. private float m_Duration;
  33. private bool m_IgnoreTimeScale;
  34. public Color startColor
  35. {
  36. get { return m_StartColor; }
  37. set { m_StartColor = value; }
  38. }
  39. public Color targetColor
  40. {
  41. get { return m_TargetColor; }
  42. set { m_TargetColor = value; }
  43. }
  44. public ColorTweenMode tweenMode
  45. {
  46. get { return m_TweenMode; }
  47. set { m_TweenMode = value; }
  48. }
  49. public float duration
  50. {
  51. get { return m_Duration; }
  52. set { m_Duration = value; }
  53. }
  54. public bool ignoreTimeScale
  55. {
  56. get { return m_IgnoreTimeScale; }
  57. set { m_IgnoreTimeScale = value; }
  58. }
  59. public void TweenValue(float floatPercentage)
  60. {
  61. if (!ValidTarget())
  62. return;
  63. var newColor = Color.Lerp(m_StartColor, m_TargetColor, floatPercentage);
  64. if (m_TweenMode == ColorTweenMode.Alpha)
  65. {
  66. newColor.r = m_StartColor.r;
  67. newColor.g = m_StartColor.g;
  68. newColor.b = m_StartColor.b;
  69. }
  70. else if (m_TweenMode == ColorTweenMode.RGB)
  71. {
  72. newColor.a = m_StartColor.a;
  73. }
  74. m_Target.Invoke(newColor);
  75. }
  76. public void AddOnChangedCallback(UnityAction<Color> callback)
  77. {
  78. if (m_Target == null)
  79. m_Target = new ColorTweenCallback();
  80. m_Target.AddListener(callback);
  81. }
  82. public bool GetIgnoreTimescale()
  83. {
  84. return m_IgnoreTimeScale;
  85. }
  86. public float GetDuration()
  87. {
  88. return m_Duration;
  89. }
  90. public bool ValidTarget()
  91. {
  92. return m_Target != null;
  93. }
  94. }
  95. // Float tween class, receives the
  96. // TweenValue callback and then sets
  97. // the value on the target.
  98. internal struct FloatTween : ITweenValue
  99. {
  100. public class FloatTweenCallback : UnityEvent<float> {}
  101. private FloatTweenCallback m_Target;
  102. private float m_StartValue;
  103. private float m_TargetValue;
  104. private float m_Duration;
  105. private bool m_IgnoreTimeScale;
  106. public float startValue
  107. {
  108. get { return m_StartValue; }
  109. set { m_StartValue = value; }
  110. }
  111. public float targetValue
  112. {
  113. get { return m_TargetValue; }
  114. set { m_TargetValue = value; }
  115. }
  116. public float duration
  117. {
  118. get { return m_Duration; }
  119. set { m_Duration = value; }
  120. }
  121. public bool ignoreTimeScale
  122. {
  123. get { return m_IgnoreTimeScale; }
  124. set { m_IgnoreTimeScale = value; }
  125. }
  126. public void TweenValue(float floatPercentage)
  127. {
  128. if (!ValidTarget())
  129. return;
  130. var newValue = Mathf.Lerp(m_StartValue, m_TargetValue, floatPercentage);
  131. m_Target.Invoke(newValue);
  132. }
  133. public void AddOnChangedCallback(UnityAction<float> callback)
  134. {
  135. if (m_Target == null)
  136. m_Target = new FloatTweenCallback();
  137. m_Target.AddListener(callback);
  138. }
  139. public bool GetIgnoreTimescale()
  140. {
  141. return m_IgnoreTimeScale;
  142. }
  143. public float GetDuration()
  144. {
  145. return m_Duration;
  146. }
  147. public bool ValidTarget()
  148. {
  149. return m_Target != null;
  150. }
  151. }
  152. // Tween runner, executes the given tween.
  153. // The coroutine will live within the given
  154. // behaviour container.
  155. internal class TweenRunner<T> where T : struct, ITweenValue
  156. {
  157. protected MonoBehaviour m_CoroutineContainer;
  158. protected IEnumerator m_Tween;
  159. // utility function for starting the tween
  160. private static IEnumerator Start(T tweenInfo)
  161. {
  162. if (!tweenInfo.ValidTarget())
  163. yield break;
  164. var elapsedTime = 0.0f;
  165. while (elapsedTime < tweenInfo.duration)
  166. {
  167. elapsedTime += tweenInfo.ignoreTimeScale ? Time.unscaledDeltaTime : Time.deltaTime;
  168. var percentage = Mathf.Clamp01(elapsedTime / tweenInfo.duration);
  169. tweenInfo.TweenValue(percentage);
  170. yield return null;
  171. }
  172. tweenInfo.TweenValue(1.0f);
  173. }
  174. public void Init(MonoBehaviour coroutineContainer)
  175. {
  176. m_CoroutineContainer = coroutineContainer;
  177. }
  178. public void StartTween(T info)
  179. {
  180. if (m_CoroutineContainer == null)
  181. {
  182. Debug.LogWarning("Coroutine container not configured... did you forget to call Init?");
  183. return;
  184. }
  185. StopTween();
  186. if (!m_CoroutineContainer.gameObject.activeInHierarchy)
  187. {
  188. info.TweenValue(1.0f);
  189. return;
  190. }
  191. m_Tween = Start(info);
  192. m_CoroutineContainer.StartCoroutine(m_Tween);
  193. }
  194. public void StopTween()
  195. {
  196. if (m_Tween != null)
  197. {
  198. m_CoroutineContainer.StopCoroutine(m_Tween);
  199. m_Tween = null;
  200. }
  201. }
  202. }
  203. }