RepeatCall.cs 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264
  1. namespace textUtility
  2. {
  3. using System;
  4. using System.Collections;
  5. using System.Collections.Generic;
  6. using UnityEngine;
  7. #if UNITY_EDITOR
  8. using UnityEditor;
  9. #endif
  10. public class RepeatCallData
  11. {
  12. //public int DelayFrame;
  13. public int DelayFramer;
  14. //public float DelayTime;
  15. public float DelayTimer;
  16. public int RepeatFrame = -1;
  17. public int RepeatFramer;
  18. public float RepeatTime = -1;
  19. public float RepeatTimer;
  20. public Action Action;
  21. public float InvokeCount = Mathf.Infinity;
  22. public float InvokeCounter = Mathf.Infinity;
  23. //public float InvokeFrame = Mathf.Infinity;
  24. //public float InvokeFramer = Mathf.Infinity;
  25. //public float InvokeTime = Mathf.Infinity;
  26. //public float InvokeTimer = Mathf.Infinity;
  27. }
  28. public class RepeatCall : MonoBehaviour
  29. {
  30. #region Config
  31. public static RepeatCall Instance
  32. {
  33. get
  34. {
  35. if (instance == null)
  36. {
  37. GameObject go = new GameObject("RepeatCall");
  38. instance = go.AddComponent<RepeatCall>();
  39. DontDestroyOnLoad(go);
  40. }
  41. return instance;
  42. }
  43. set { instance = value; }
  44. }
  45. private static RepeatCall instance;
  46. private static float DeltaTime
  47. {
  48. get
  49. {
  50. if (Application.isPlaying)
  51. {
  52. return Time.deltaTime;
  53. }
  54. else //�༭��ģʽ��ʹ��
  55. {
  56. #if UNITY_EDITOR
  57. double deltaTime = EditorApplication.timeSinceStartup - LastTimeSinceStartup;
  58. LastTimeSinceStartup = EditorApplication.timeSinceStartup;
  59. return (float)deltaTime;
  60. #else
  61. throw new Exception();
  62. #endif
  63. }
  64. }
  65. }
  66. private static double LastTimeSinceStartup;
  67. private static Dictionary<Coroutine, RepeatCallData> RepeatCallDataDictionary = new Dictionary<Coroutine, RepeatCallData>();
  68. #if UNITY_EDITOR
  69. //�༭��ģʽ��ʹ��
  70. private static Dictionary<IEnumerator, EditorApplication.CallbackFunction> CallbackFunctionDictionary = new Dictionary<IEnumerator, EditorApplication.CallbackFunction>();
  71. private static Dictionary<IEnumerator, RepeatCallData> RepeatCallDataDictionaryForEditor = new Dictionary<IEnumerator, RepeatCallData>();
  72. #endif
  73. #endregion
  74. public static object Call(RepeatCallData repeatCallData)
  75. {
  76. //repeatCallData.DelayFramer = repeatCallData.DelayFrame;
  77. //repeatCallData.DelayTimer = repeatCallData.DelayTime;
  78. repeatCallData.RepeatFramer = repeatCallData.RepeatFrame;
  79. repeatCallData.RepeatTimer = repeatCallData.RepeatTime;
  80. repeatCallData.InvokeCounter = repeatCallData.InvokeCount;
  81. //repeatCallData.InvokeFramer = repeatCallData.InvokeFrame;
  82. //repeatCallData.InvokeTimer = repeatCallData.InvokeTime;
  83. if (Application.isPlaying)
  84. {
  85. Coroutine coroutine = Instance.StartCoroutine(repeatCall(repeatCallData));
  86. RepeatCallDataDictionary.Add(coroutine, repeatCallData);
  87. return coroutine;
  88. }
  89. else
  90. {
  91. #if UNITY_EDITOR
  92. IEnumerator enumerator = repeatCall(repeatCallData);
  93. RepeatCallDataDictionaryForEditor.Add(enumerator, repeatCallData);
  94. EditorApplication.CallbackFunction callbackFunction = () => UpdateEnumerators(enumerator);
  95. CallbackFunctionDictionary.Add(enumerator, callbackFunction);
  96. callbackFunction.Invoke();
  97. EditorApplication.update += callbackFunction;
  98. LastTimeSinceStartup = EditorApplication.timeSinceStartup;
  99. return enumerator;
  100. #else
  101. throw new Exception();
  102. #endif
  103. }
  104. }
  105. public static void PauseRepeatCall(object obj)
  106. {
  107. if (Application.isPlaying)
  108. {
  109. Instance.StopCoroutine((Coroutine) obj);
  110. }
  111. else
  112. {
  113. #if UNITY_EDITOR
  114. EditorApplication.CallbackFunction callbackFunction = CallbackFunctionDictionary[(IEnumerator)obj];
  115. EditorApplication.update -= callbackFunction;
  116. #endif
  117. }
  118. }
  119. public static void ResumeRepeatCall(object obj)
  120. {
  121. if (Application.isPlaying)
  122. {
  123. RepeatCallData repeatCallData = RepeatCallDataDictionary[(Coroutine)obj];
  124. Call(repeatCallData);
  125. }
  126. else
  127. {
  128. #if UNITY_EDITOR
  129. RepeatCallData repeatCallData = RepeatCallDataDictionaryForEditor[(IEnumerator)obj];
  130. Call(repeatCallData);
  131. #endif
  132. }
  133. }
  134. private static void UpdateEnumerators(IEnumerator enumerator) //�༭��ģʽ��ʹ��
  135. {
  136. enumerator.MoveNext();
  137. }
  138. private static IEnumerator repeatCall(RepeatCallData repeatCallData)
  139. {
  140. //Debug.Log(repeatCallData.DelayFramer + " " + repeatCallData.DelayTimer);
  141. if (repeatCallData.DelayFramer > 0)
  142. {
  143. while (repeatCallData.DelayFramer > 0)
  144. {
  145. repeatCallData.DelayFramer--;
  146. yield return null;
  147. }
  148. if (InvokeRepeatCall(repeatCallData))
  149. {
  150. yield break;
  151. }
  152. }
  153. else if (repeatCallData.DelayTimer > 0)
  154. {
  155. yield return null; //����StartCoroutine��������ִ�е���һ��yield
  156. while (repeatCallData.DelayTimer > 0)
  157. {
  158. repeatCallData.DelayTimer -= DeltaTime;
  159. yield return null;
  160. }
  161. if (InvokeRepeatCall(repeatCallData))
  162. {
  163. yield break;
  164. }
  165. }
  166. else
  167. {
  168. if (InvokeRepeatCall(repeatCallData))
  169. {
  170. yield break;
  171. }
  172. else
  173. {
  174. yield return null;
  175. }
  176. if (repeatCallData.RepeatFramer > -1)
  177. {
  178. while (repeatCallData.RepeatFramer > 0)
  179. {
  180. repeatCallData.RepeatFramer--;
  181. yield return null;
  182. }
  183. repeatCallData.RepeatFramer = repeatCallData.RepeatFrame;
  184. if (InvokeRepeatCall(repeatCallData))
  185. {
  186. yield break;
  187. }
  188. }
  189. else if (repeatCallData.RepeatTimer > -1)
  190. {
  191. while (repeatCallData.RepeatTimer > 0)
  192. {
  193. repeatCallData.RepeatTimer -= DeltaTime;
  194. yield return null;
  195. }
  196. repeatCallData.RepeatTimer = repeatCallData.RepeatTime;
  197. if (InvokeRepeatCall(repeatCallData))
  198. {
  199. yield break;
  200. }
  201. }
  202. else
  203. {
  204. throw new Exception();
  205. }
  206. }
  207. }
  208. private static bool InvokeRepeatCall(RepeatCallData repeatCallData)
  209. {
  210. repeatCallData.Action.Invoke();
  211. if (--repeatCallData.InvokeCounter <= 0)
  212. {
  213. return true;
  214. }
  215. else
  216. {
  217. return false;
  218. }
  219. }
  220. }
  221. public class DelayCall
  222. {
  223. public static object Call(int delayFrame, Action action)
  224. {
  225. RepeatCallData repeatCallData = new RepeatCallData();
  226. repeatCallData.DelayFramer = delayFrame;
  227. repeatCallData.InvokeCount = 1;
  228. repeatCallData.Action = action;
  229. return RepeatCall.Call(repeatCallData);
  230. }
  231. public static object Call(float delayTime, Action action)
  232. {
  233. RepeatCallData repeatCallData = new RepeatCallData();
  234. repeatCallData.DelayTimer = delayTime;
  235. repeatCallData.InvokeCount = 1;
  236. repeatCallData.Action = action;
  237. return RepeatCall.Call(repeatCallData);
  238. }
  239. }
  240. }