You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

245 lines
6.2 KiB

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