Timer.cs 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207
  1. namespace TurnTheGameOn.Timer
  2. {
  3. using TMPro;
  4. using UnityEngine;
  5. using UnityEngine.UI;
  6. using UnityEngine.Events;
  7. using System;
  8. using System.Collections;
  9. using UnityEngine.SceneManagement;
  10. [System.Serializable] public class DisplayOptions {
  11. public bool milliseconds = true, seconds = true, minutes = true, hours = true, days = true;
  12. }
  13. [System.Serializable] public class TimerFormat {
  14. public bool milliseconds = true, seconds = true, minutes = true, hours = true;
  15. }
  16. [System.Serializable] public class LeadingZero {
  17. public bool seconds = true, minutes = true, hours = true;
  18. }
  19. [ExecuteInEditMode]
  20. public class Timer : MonoBehaviour {
  21. public enum TimerType {CountUp, CountDown, CountUpInfinite}
  22. public enum LoadSceneOn {Disabled, TimesUp, SpecificTime}
  23. public enum TimerState {Disabled, Counting}
  24. public enum TextType {DefaultText, TextMeshProUGUI}
  25. public DisplayOptions displayOptions;
  26. public TimerFormat timerFormat;
  27. public LeadingZero leadingZero;
  28. private string ms, s, m, d, h;
  29. public TimerState timerState;
  30. public bool useSystemTime;
  31. private DateTime systemDateTime;
  32. public float gameTime;
  33. public TextType textType;
  34. public Text timerTextDefault;
  35. public TextMeshProUGUI timerTextTMPUGUI;
  36. public float timerSpeed = 1;
  37. public int day;
  38. public int hour;
  39. public int minute;
  40. public int second;
  41. public int millisecond;
  42. public bool setZeroTimescale;
  43. public bool setStartTimeForCountUp;
  44. public UnityEvent timesUpEvent;
  45. public GameObject[] destroyOnFinish;
  46. [HideInInspector()] public TimerType timerType;
  47. [HideInInspector()] public float startTime;
  48. [HideInInspector()] public float finishTime;
  49. [HideInInspector()] public LoadSceneOn loadSceneOn;
  50. [HideInInspector()] public string loadSceneName;
  51. [HideInInspector()] public float timeToLoadScene;
  52. string FormatSeconds(float elapsed){
  53. if (timerType == TimerType.CountUpInfinite) {
  54. if (useSystemTime) {
  55. CheckDisplayOptions ();
  56. gameTime = ((float)DateTime.Now.Hour + ((float)DateTime.Now.Minute) + (float)DateTime.Now.Second);
  57. millisecond = (int)DateTime.Now.Millisecond;
  58. second = (int)DateTime.Now.Second;
  59. minute = (int)DateTime.Now.Minute;
  60. hour = (int)DateTime.Now.Hour;
  61. day = (int)DateTime.Now.DayOfYear;
  62. return String.Format (d + h + m + s + ms, day, hour, minute, second, millisecond);
  63. } else {
  64. CheckDisplayOptions ();
  65. TimeSpan t = TimeSpan.FromSeconds (elapsed);
  66. day = t.Days;
  67. hour = t.Hours;
  68. minute = t.Minutes;
  69. second = t.Seconds;
  70. millisecond = t.Milliseconds;
  71. return String.Format ( d + h + m + s + ms, t.Days, t.Hours, t.Minutes, t.Seconds, t.Milliseconds);
  72. }
  73. } else {
  74. TimeSpan t = TimeSpan.FromSeconds (elapsed);
  75. CheckTimerOptions ();
  76. day = t.Days;
  77. hour = t.Hours;
  78. minute = t.Minutes;
  79. second = t.Seconds;
  80. millisecond = t.Milliseconds;
  81. if (!leadingZero.seconds && t.Seconds < 10 && s == "{2:D2}") s = "{2:D1}";
  82. if (!leadingZero.minutes && t.Minutes < 10 && m == "{1:D2}:") m = "{1:D1}:";
  83. if (!leadingZero.hours && t.Hours < 10 && h == "{0:D2}:") h = "{0:D1}:";
  84. return String.Format ( h + m + s + ms, t.Hours, t.Minutes, t.Seconds, t.Milliseconds);
  85. }
  86. }
  87. void UpdateUIText ()
  88. {
  89. switch (textType)
  90. {
  91. case TextType.DefaultText:
  92. if(timerTextDefault != null) timerTextDefault.text = FormatSeconds(gameTime);
  93. break;
  94. case TextType.TextMeshProUGUI:
  95. if(timerTextTMPUGUI != null) timerTextTMPUGUI.text = FormatSeconds(gameTime);
  96. break;
  97. }
  98. }
  99. void CheckDisplayOptions()
  100. {
  101. ms = displayOptions.milliseconds ? ".{4:D3}" : "";
  102. s = displayOptions.seconds ? ".{3:D2}" : "";
  103. m = displayOptions.minutes ? "{2:D2}:" : "";
  104. h = displayOptions.hours ? "{1:D2}:" : "";
  105. d = displayOptions.days ? "{0:D3}:" : "";
  106. }
  107. void CheckTimerOptions()
  108. {
  109. ms = timerFormat.milliseconds ? ".{3:D3}" : "";
  110. s = timerFormat.seconds ? "{2:D2}" : "";
  111. m = timerFormat.minutes ? "{1:D2}:" : "";
  112. h = timerFormat.hours ? "{0:D2}:" : "";
  113. }
  114. void Start () {
  115. if(timerState == TimerState.Counting){
  116. UpdateUIText();
  117. if (timerType == TimerType.CountUp || timerType == TimerType.CountUpInfinite) gameTime = setStartTimeForCountUp ? startTime : 0;
  118. if (timerType == TimerType.CountDown) gameTime = startTime;
  119. }
  120. }
  121. void Update () {
  122. if (timerTextDefault != null){
  123. timerTextDefault.text = FormatSeconds (gameTime);
  124. }
  125. else if (useSystemTime) {
  126. gameTime = ((float)DateTime.Now.Hour + ((float)DateTime.Now.Minute) + (float)DateTime.Now.Second);
  127. second = (int)DateTime.Now.Second;
  128. minute = (int)DateTime.Now.Minute;
  129. hour = (int)DateTime.Now.Hour;
  130. }
  131. #if UNITY_EDITOR
  132. if(!Application.isPlaying){
  133. if (timerType == TimerType.CountUp) gameTime = 0;
  134. if (timerType == TimerType.CountDown) gameTime = startTime;
  135. UpdateUIText();
  136. }
  137. #endif
  138. if (timerState == TimerState.Counting) {
  139. if (timerType == TimerType.CountUp) {
  140. gameTime += 1 * Time.deltaTime * timerSpeed;
  141. if (gameTime >= timeToLoadScene) {
  142. if (loadSceneOn == LoadSceneOn.SpecificTime) SceneManager.LoadScene (loadSceneName);
  143. }
  144. }
  145. if (timerType == TimerType.CountDown) {
  146. gameTime -= 1 * Time.deltaTime * timerSpeed;
  147. if (gameTime <= timeToLoadScene) {
  148. if (loadSceneOn == LoadSceneOn.SpecificTime) SceneManager.LoadScene (loadSceneName);
  149. }
  150. }
  151. if (timerType == TimerType.CountUpInfinite) {
  152. if (!useSystemTime) gameTime += 1 * Time.deltaTime * timerSpeed;
  153. }
  154. if (timerType == TimerType.CountDown && gameTime <= 0) {
  155. StopTimer ();
  156. timesUpEvent.Invoke();
  157. for (int i = 0; i < destroyOnFinish.Length; i++) Destroy (destroyOnFinish [i]);
  158. if (loadSceneOn == LoadSceneOn.TimesUp) SceneManager.LoadScene (loadSceneName);
  159. }
  160. if (timerType == TimerType.CountUp && gameTime >= finishTime) {
  161. timesUpEvent.Invoke();
  162. StopTimer ();
  163. for (int i = 0; i < destroyOnFinish.Length; i++) Destroy (destroyOnFinish [i]);
  164. if (loadSceneOn == LoadSceneOn.TimesUp) SceneManager.LoadScene (loadSceneName);
  165. }
  166. UpdateUIText();
  167. }
  168. }
  169. public float GetTimerValue () { return gameTime; }
  170. public void AddTime (float value) { gameTime += value; }
  171. [ContextMenu("Start Timer")] public void StartTimer() { timerState = TimerState.Counting; }
  172. [ContextMenu("Stop Timer")] public void StopTimer(){
  173. timerState = TimerState.Disabled;
  174. if (setZeroTimescale) Time.timeScale = 0;
  175. if (gameTime < 0.0f) gameTime = 0.0f;
  176. UpdateUIText();
  177. }
  178. [ContextMenu("Restart Timer")] public void RestartTimer(){
  179. if (timerType == TimerType.CountDown) gameTime = startTime;
  180. else gameTime = 0;
  181. UpdateUIText();
  182. StartTimer ();
  183. }
  184. [ContextMenu("Reset Timer")] public void ResetTimer(){
  185. if (timerType == TimerType.CountDown) gameTime = startTime;
  186. else gameTime = 0;
  187. UpdateUIText();
  188. }
  189. }
  190. }