CooldownButton.cs 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197
  1. /// Credit SimonDarksideJ
  2. /// Sourced from my head
  3. using UnityEngine.Events;
  4. using UnityEngine.EventSystems;
  5. namespace UnityEngine.UI.Extensions
  6. {
  7. [AddComponentMenu("UI/Extensions/Cooldown Button")]
  8. public class CooldownButton : MonoBehaviour, IPointerDownHandler
  9. {
  10. #region Sub-Classes
  11. [System.Serializable]
  12. public class CooldownButtonEvent : UnityEvent<PointerEventData.InputButton> { }
  13. #endregion
  14. #region Private variables
  15. [SerializeField]
  16. private float cooldownTimeout;
  17. [SerializeField]
  18. private float cooldownSpeed = 1;
  19. [SerializeField][ReadOnly]
  20. private bool cooldownActive;
  21. [SerializeField][ReadOnly]
  22. private bool cooldownInEffect;
  23. [SerializeField][ReadOnly]
  24. private float cooldownTimeElapsed;
  25. [SerializeField][ReadOnly]
  26. private float cooldownTimeRemaining;
  27. [SerializeField][ReadOnly]
  28. private int cooldownPercentRemaining;
  29. [SerializeField][ReadOnly]
  30. private int cooldownPercentComplete;
  31. PointerEventData buttonSource;
  32. #endregion
  33. #region Public Properties
  34. public float CooldownTimeout
  35. {
  36. get { return cooldownTimeout; }
  37. set { cooldownTimeout = value; }
  38. }
  39. public float CooldownSpeed
  40. {
  41. get { return cooldownSpeed; }
  42. set { cooldownSpeed = value; }
  43. }
  44. public bool CooldownInEffect
  45. {
  46. get { return cooldownInEffect; }
  47. }
  48. public bool CooldownActive
  49. {
  50. get { return cooldownActive; }
  51. set { cooldownActive = value; }
  52. }
  53. public float CooldownTimeElapsed
  54. {
  55. get { return cooldownTimeElapsed; }
  56. set { cooldownTimeElapsed = value; }
  57. }
  58. public float CooldownTimeRemaining
  59. {
  60. get { return cooldownTimeRemaining; }
  61. }
  62. public int CooldownPercentRemaining
  63. {
  64. get { return cooldownPercentRemaining; }
  65. }
  66. public int CooldownPercentComplete
  67. {
  68. get { return cooldownPercentComplete; }
  69. }
  70. #endregion
  71. #region Events
  72. [Tooltip("Event that fires when a button is initially pressed down")]
  73. public CooldownButtonEvent OnCooldownStart;
  74. [Tooltip("Event that fires when a button is released")]
  75. public CooldownButtonEvent OnButtonClickDuringCooldown;
  76. [Tooltip("Event that continually fires while a button is held down")]
  77. public CooldownButtonEvent OnCoolDownFinish;
  78. #endregion
  79. #region Update
  80. // Update is called once per frame
  81. void Update()
  82. {
  83. if (CooldownActive)
  84. {
  85. cooldownTimeRemaining -= Time.deltaTime * cooldownSpeed;
  86. cooldownTimeElapsed = CooldownTimeout - CooldownTimeRemaining;
  87. if (cooldownTimeRemaining < 0)
  88. {
  89. StopCooldown();
  90. }
  91. else
  92. {
  93. cooldownPercentRemaining = (int)(100 * cooldownTimeRemaining * CooldownTimeout / 100);
  94. cooldownPercentComplete = (int)((CooldownTimeout - cooldownTimeRemaining) / CooldownTimeout * 100);
  95. }
  96. }
  97. }
  98. #endregion
  99. #region Public Methods
  100. /// <summary>
  101. /// Pause Cooldown without resetting values, allows Restarting of cooldown
  102. /// </summary>
  103. public void PauseCooldown()
  104. {
  105. if (CooldownInEffect)
  106. {
  107. CooldownActive = false;
  108. }
  109. }
  110. /// <summary>
  111. /// Restart a paused cooldown
  112. /// </summary>
  113. public void RestartCooldown()
  114. {
  115. if (CooldownInEffect)
  116. {
  117. CooldownActive = true;
  118. }
  119. }
  120. /// <summary>
  121. /// Start a cooldown from outside
  122. /// </summary>
  123. public void StartCooldown()
  124. {
  125. PointerEventData emptySource = new PointerEventData(EventSystem.current);
  126. buttonSource = emptySource;
  127. OnCooldownStart.Invoke(emptySource.button);
  128. cooldownTimeRemaining = cooldownTimeout;
  129. CooldownActive = cooldownInEffect = true;
  130. }
  131. /// <summary>
  132. /// Stop a running Cooldown and reset all values
  133. /// </summary>
  134. public void StopCooldown()
  135. {
  136. cooldownTimeElapsed = CooldownTimeout;
  137. cooldownTimeRemaining = 0;
  138. cooldownPercentRemaining = 0;
  139. cooldownPercentComplete = 100;
  140. cooldownActive = cooldownInEffect = false;
  141. if (OnCoolDownFinish != null) OnCoolDownFinish.Invoke(buttonSource.button);
  142. }
  143. /// <summary>
  144. /// Stop a running Cooldown and retain current values
  145. /// </summary>
  146. public void CancelCooldown()
  147. {
  148. cooldownActive = cooldownInEffect = false;
  149. }
  150. #endregion
  151. #region IPointerDownHandler
  152. void IPointerDownHandler.OnPointerDown(PointerEventData eventData)
  153. {
  154. buttonSource = eventData;
  155. if (CooldownInEffect)
  156. {
  157. if (OnButtonClickDuringCooldown != null) OnButtonClickDuringCooldown.Invoke(eventData.button);
  158. }
  159. if (!CooldownInEffect)
  160. {
  161. if(OnCooldownStart != null) OnCooldownStart.Invoke(eventData.button);
  162. cooldownTimeRemaining = cooldownTimeout;
  163. cooldownActive = cooldownInEffect = true;
  164. }
  165. }
  166. #endregion
  167. }
  168. }