LivesCounterUI.cs 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202
  1. using System;
  2. using UnityEngine;
  3. using System.Collections;
  4. using UnityEngine.UI;
  5. using TMPro;
  6. using ICTS.Localization;
  7. /// <summary>
  8. /// This component is responsible for updating the UI of the lives counter. This includes
  9. /// the number of current lives available, the time to replenish the live (if it's not full),
  10. /// and also a circular graphical representation of how much lives are left.
  11. /// It will also give visual feedback when a life charges or discharges
  12. /// </summary>
  13. public class LivesCounterUI : MonoBehaviour
  14. {
  15. public TextMeshProUGUI livesCountLabel;
  16. public TextMeshProUGUI timeLeftLabel;
  17. public Image livesCircle;
  18. public Transform feedbackHeart;
  19. const float FADE_TIME = 1;
  20. int _prevLives;
  21. Vector3 _originalHeartScale;
  22. Image _feedbackHeartSprite;
  23. void Awake()
  24. {
  25. _feedbackHeartSprite = feedbackHeart.GetComponent<Image>();
  26. _originalHeartScale = feedbackHeart.transform.localScale;
  27. NotificationCenter.AddListener(OnGameStart, NotificationType.GameStart);
  28. NotificationCenter.AddListener(OnGameOver, NotificationType.GameOver);
  29. DebugViewManager.OnDebugView += OnDebugView;
  30. _prevLives = LivesManager.Instance.Lives;
  31. }
  32. void OnDestroy()
  33. {
  34. NotificationCenter.RemoveListener(OnGameStart, NotificationType.GameStart);
  35. DebugViewManager.OnDebugView -= OnDebugView;
  36. }
  37. void OnEnable()
  38. {
  39. UpdateLivesCounterAndLivesCircle();
  40. StartCoroutine(UpdateUICoroutine());
  41. StopCoroutine(DelayedHideCoroutine());
  42. }
  43. void OnDebugView()
  44. {
  45. if (GUILayout.Button("Reset Lives"))
  46. {
  47. for (int i = LivesManager.Instance.Lives; i < LivesManager.MAX_RECHARGABLE_LIVES; i++)
  48. {
  49. LivesManager.Instance.RechargeLife();
  50. }
  51. }
  52. if (GUILayout.Button("Zero Lives"))
  53. {
  54. while (LivesManager.Instance.Lives > 0)
  55. {
  56. LivesManager.Instance.ConsumeLife();
  57. }
  58. }
  59. }
  60. /// <summary>
  61. /// Updates the UI components every half a second ... that should be enough.
  62. /// Note that it's not ever 1 second since one might experience a "jump" of two seconds visually,
  63. /// due to WaitForSeconds not being accurate. With 0.5f this should be more unlike to occur
  64. /// </summary>
  65. IEnumerator UpdateUICoroutine()
  66. {
  67. while (true)
  68. {
  69. int numOfLives = LivesManager.Instance.Lives;
  70. if (_prevLives < numOfLives)
  71. {
  72. IncreaseLivesFeedback();
  73. }
  74. if (_prevLives != numOfLives)
  75. {
  76. UpdateLivesCounterAndLivesCircle();
  77. }
  78. _prevLives = numOfLives;
  79. if (LivesManager.Instance.IsFull)
  80. {
  81. timeLeftLabel.text = Localization.instance.Get("lifeBank.full");
  82. } else
  83. {
  84. timeLeftLabel.text = "";
  85. //timeLeftLabel.text = UIUtils.FormatSeconds(LivesManager.Instance.SecondsLeftToReplenishALife);
  86. }
  87. yield return new WaitForSeconds(0.5f);
  88. }
  89. }
  90. void UpdateLivesCounterAndLivesCircle()
  91. {
  92. int numOfLives = LivesManager.Instance.Lives;
  93. if (!PlayerPrefs.HasKey("Live"))
  94. {
  95. PlayerPrefs.SetInt("Live", LivesManager.MAX_RECHARGABLE_LIVES);
  96. numOfLives = LivesManager.MAX_RECHARGABLE_LIVES;
  97. PlayerPrefs.Save();
  98. LivesManager.Instance.Lives = LivesManager.MAX_RECHARGABLE_LIVES;
  99. }
  100. livesCountLabel.text = numOfLives.ToString();
  101. float newFilledAmount = numOfLives / (float)LivesManager.MAX_RECHARGABLE_LIVES;
  102. iTween.ValueTo(livesCircle.gameObject, iTween.Hash(
  103. "from", livesCircle.fillAmount,
  104. "to", newFilledAmount,
  105. "easeType", iTween.EaseType.easeOutCubic,
  106. "onupdate", "OniTweenUpdateLivesCircle",
  107. "onupdatetarget", gameObject));
  108. }
  109. void OnGameStart(Notification note)
  110. {
  111. AVDebug.Assert(LivesManager.Instance.CanPlay, "Trying to play when he doesn't have lives! Should never happen.");
  112. //LivesManager.Instance.ConsumeLife();
  113. DecreaseLivesFeedback();
  114. }
  115. void OnGameOver(Notification note)
  116. {
  117. AVDebug.Assert(LivesManager.Instance.CanPlay, "Trying to play when he doesn't have lives! Should never happen.");
  118. //LivesManager.Instance.ConsumeLife();
  119. //DecreaseLivesFeedback();
  120. }
  121. #region Visual Feedback
  122. void IncreaseLivesFeedback()
  123. {
  124. SoundManager.Play(SoundEvent.lifeIncrement);
  125. feedbackHeart.localScale = _originalHeartScale * 2;
  126. iTween.ScaleTo(feedbackHeart.gameObject, iTween.Hash(
  127. "scale", _originalHeartScale,
  128. "time", 1));
  129. _feedbackHeartSprite.color = new Color(_feedbackHeartSprite.color.r, _feedbackHeartSprite.color.g, _feedbackHeartSprite.color.b,0);
  130. FadeHeartTo(1);
  131. StartCoroutine(FadeOutIncreaseFeedbackHeartCoroutine());
  132. }
  133. IEnumerator FadeOutIncreaseFeedbackHeartCoroutine()
  134. {
  135. yield return new WaitForSeconds(FADE_TIME);
  136. FadeHeartTo(0);
  137. }
  138. void DecreaseLivesFeedback()
  139. {
  140. feedbackHeart.localScale = _originalHeartScale;
  141. iTween.ScaleTo(feedbackHeart.gameObject, iTween.Hash(
  142. "scale", _originalHeartScale * 2,
  143. "time", 1));
  144. _feedbackHeartSprite.color = new Color(_feedbackHeartSprite.color.r, _feedbackHeartSprite.color.g, _feedbackHeartSprite.color.b, 1);
  145. FadeHeartTo(0);
  146. if(gameObject.activeSelf)
  147. try
  148. {
  149. StartCoroutine(DelayedHideCoroutine());
  150. }
  151. catch (Exception e)
  152. {
  153. Debug.Log(e);
  154. }
  155. }
  156. void FadeHeartTo(float toAlpha)
  157. {
  158. iTween.ValueTo(_feedbackHeartSprite.gameObject, iTween.Hash(
  159. "from", _feedbackHeartSprite.color.a,
  160. "to", toAlpha,
  161. "time", FADE_TIME,
  162. "onupdate", "OniTweenUpdateSpriteAlpha",
  163. "onupdatetarget", gameObject));
  164. }
  165. void OniTweenUpdateSpriteAlpha(float newAlpha)
  166. {
  167. _feedbackHeartSprite.color = new Color(_feedbackHeartSprite.color.r, _feedbackHeartSprite.color.g, _feedbackHeartSprite.color.b, newAlpha);
  168. }
  169. void OniTweenUpdateLivesCircle(float newFilledAmount)
  170. {
  171. livesCircle.fillAmount = newFilledAmount;
  172. }
  173. #endregion
  174. IEnumerator DelayedHideCoroutine()
  175. {
  176. yield return new WaitForSeconds(FADE_TIME);
  177. transform.parent.SendMessageUpwards("Hide");
  178. }
  179. }