MovieClip.cs 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414
  1. using UnityEngine;
  2. namespace FairyGUI
  3. {
  4. /// <summary>
  5. ///
  6. /// </summary>
  7. public class MovieClip : Image
  8. {
  9. /// <summary>
  10. ///
  11. /// </summary>
  12. public class Frame
  13. {
  14. public NTexture texture;
  15. public float addDelay;
  16. }
  17. /// <summary>
  18. ///
  19. /// </summary>
  20. public float interval;
  21. /// <summary>
  22. ///
  23. /// </summary>
  24. public bool swing;
  25. /// <summary>
  26. ///
  27. /// </summary>
  28. public float repeatDelay;
  29. /// <summary>
  30. ///
  31. /// </summary>
  32. public float timeScale;
  33. /// <summary>
  34. /// Whether to ignore Unity time scale.
  35. /// </summary>
  36. public bool ignoreEngineTimeScale;
  37. Frame[] _frames;
  38. int _frameCount;
  39. int _frame;
  40. bool _playing;
  41. int _start;
  42. int _end;
  43. int _times;
  44. int _endAt;
  45. int _status; //0-none, 1-next loop, 2-ending, 3-ended
  46. float _frameElapsed; //当前帧延迟
  47. bool _reversed;
  48. int _repeatedCount;
  49. TimerCallback _timerDelegate;
  50. EventListener _onPlayEnd;
  51. /// <summary>
  52. ///
  53. /// </summary>
  54. public MovieClip()
  55. {
  56. interval = 0.1f;
  57. _playing = true;
  58. _timerDelegate = OnTimer;
  59. timeScale = 1;
  60. ignoreEngineTimeScale = false;
  61. if (Application.isPlaying)
  62. {
  63. onAddedToStage.Add(OnAddedToStage);
  64. onRemovedFromStage.Add(OnRemoveFromStage);
  65. }
  66. SetPlaySettings();
  67. }
  68. /// <summary>
  69. ///
  70. /// </summary>
  71. public EventListener onPlayEnd
  72. {
  73. get { return _onPlayEnd ?? (_onPlayEnd = new EventListener(this, "onPlayEnd")); }
  74. }
  75. /// <summary>
  76. ///
  77. /// </summary>
  78. public Frame[] frames
  79. {
  80. get
  81. {
  82. return _frames;
  83. }
  84. set
  85. {
  86. _frames = value;
  87. _scale9Grid = null;
  88. _scaleByTile = false;
  89. if (_frames == null)
  90. {
  91. _frameCount = 0;
  92. graphics.texture = null;
  93. CheckTimer();
  94. return;
  95. }
  96. _frameCount = frames.Length;
  97. if (_end == -1 || _end > _frameCount - 1)
  98. _end = _frameCount - 1;
  99. if (_endAt == -1 || _endAt > _frameCount - 1)
  100. _endAt = _frameCount - 1;
  101. if (_frame < 0 || _frame > _frameCount - 1)
  102. _frame = _frameCount - 1;
  103. InvalidateBatchingState();
  104. _frameElapsed = 0;
  105. _repeatedCount = 0;
  106. _reversed = false;
  107. DrawFrame();
  108. CheckTimer();
  109. }
  110. }
  111. /// <summary>
  112. ///
  113. /// </summary>
  114. public bool playing
  115. {
  116. get { return _playing; }
  117. set
  118. {
  119. if (_playing != value)
  120. {
  121. _playing = value;
  122. CheckTimer();
  123. }
  124. }
  125. }
  126. /// <summary>
  127. ///
  128. /// </summary>
  129. public int frame
  130. {
  131. get { return _frame; }
  132. set
  133. {
  134. if (_frame != value)
  135. {
  136. if (_frames != null && value >= _frameCount)
  137. value = _frameCount - 1;
  138. _frame = value;
  139. _frameElapsed = 0;
  140. DrawFrame();
  141. }
  142. }
  143. }
  144. /// <summary>
  145. ///
  146. /// </summary>
  147. public void Rewind()
  148. {
  149. _frame = 0;
  150. _frameElapsed = 0;
  151. _reversed = false;
  152. _repeatedCount = 0;
  153. DrawFrame();
  154. }
  155. /// <summary>
  156. ///
  157. /// </summary>
  158. /// <param name="anotherMc"></param>
  159. public void SyncStatus(MovieClip anotherMc)
  160. {
  161. _frame = anotherMc._frame;
  162. _frameElapsed = anotherMc._frameElapsed;
  163. _reversed = anotherMc._reversed;
  164. _repeatedCount = anotherMc._repeatedCount;
  165. DrawFrame();
  166. }
  167. /// <summary>
  168. ///
  169. /// </summary>
  170. /// <param name="time"></param>
  171. public void Advance(float time)
  172. {
  173. int beginFrame = _frame;
  174. bool beginReversed = _reversed;
  175. float backupTime = time;
  176. while (true)
  177. {
  178. float tt = interval + _frames[_frame].addDelay;
  179. if (_frame == 0 && _repeatedCount > 0)
  180. tt += repeatDelay;
  181. if (time < tt)
  182. {
  183. _frameElapsed = 0;
  184. break;
  185. }
  186. time -= tt;
  187. if (swing)
  188. {
  189. if (_reversed)
  190. {
  191. _frame--;
  192. if (_frame <= 0)
  193. {
  194. _frame = 0;
  195. _repeatedCount++;
  196. _reversed = !_reversed;
  197. }
  198. }
  199. else
  200. {
  201. _frame++;
  202. if (_frame > _frameCount - 1)
  203. {
  204. _frame = Mathf.Max(0, _frameCount - 2);
  205. _repeatedCount++;
  206. _reversed = !_reversed;
  207. }
  208. }
  209. }
  210. else
  211. {
  212. _frame++;
  213. if (_frame > _frameCount - 1)
  214. {
  215. _frame = 0;
  216. _repeatedCount++;
  217. }
  218. }
  219. if (_frame == beginFrame && _reversed == beginReversed) //走了一轮了
  220. {
  221. float roundTime = backupTime - time; //这就是一轮需要的时间
  222. time -= Mathf.FloorToInt(time / roundTime) * roundTime; //跳过
  223. }
  224. }
  225. DrawFrame();
  226. }
  227. /// <summary>
  228. ///
  229. /// </summary>
  230. public void SetPlaySettings()
  231. {
  232. SetPlaySettings(0, -1, 0, -1);
  233. }
  234. /// <summary>
  235. /// 从start帧开始,播放到end帧(-1表示结尾),重复times次(0表示无限循环),循环结束后,停止在endAt帧(-1表示参数end)
  236. /// </summary>
  237. /// <param name="start"></param>
  238. /// <param name="end"></param>
  239. /// <param name="times"></param>
  240. /// <param name="endAt"></param>
  241. public void SetPlaySettings(int start, int end, int times, int endAt)
  242. {
  243. _start = start;
  244. _end = end;
  245. if (_end == -1 || _end > _frameCount - 1)
  246. _end = _frameCount - 1;
  247. _times = times;
  248. _endAt = endAt;
  249. if (_endAt == -1)
  250. _endAt = _end;
  251. _status = 0;
  252. this.frame = start;
  253. }
  254. void OnAddedToStage()
  255. {
  256. if (_playing && _frameCount > 0)
  257. Timers.inst.AddUpdate(_timerDelegate);
  258. }
  259. void OnRemoveFromStage()
  260. {
  261. Timers.inst.Remove(_timerDelegate);
  262. }
  263. void CheckTimer()
  264. {
  265. if (!Application.isPlaying)
  266. return;
  267. if (_playing && _frameCount > 0 && this.stage != null)
  268. Timers.inst.AddUpdate(_timerDelegate);
  269. else
  270. Timers.inst.Remove(_timerDelegate);
  271. }
  272. void OnTimer(object param)
  273. {
  274. if (!_playing || _frameCount == 0 || _status == 3)
  275. return;
  276. float dt;
  277. if (ignoreEngineTimeScale)
  278. {
  279. dt = Time.unscaledDeltaTime;
  280. if (dt > 0.1f)
  281. dt = 0.1f;
  282. }
  283. else
  284. dt = Time.deltaTime;
  285. if (timeScale != 1)
  286. dt *= timeScale;
  287. _frameElapsed += dt;
  288. float tt = interval + _frames[_frame].addDelay;
  289. if (_frame == 0 && _repeatedCount > 0)
  290. tt += repeatDelay;
  291. if (_frameElapsed < tt)
  292. return;
  293. _frameElapsed -= tt;
  294. if (_frameElapsed > interval)
  295. _frameElapsed = interval;
  296. if (swing)
  297. {
  298. if (_reversed)
  299. {
  300. _frame--;
  301. if (_frame <= 0)
  302. {
  303. _frame = 0;
  304. _repeatedCount++;
  305. _reversed = !_reversed;
  306. }
  307. }
  308. else
  309. {
  310. _frame++;
  311. if (_frame > _frameCount - 1)
  312. {
  313. _frame = Mathf.Max(0, _frameCount - 2);
  314. _repeatedCount++;
  315. _reversed = !_reversed;
  316. }
  317. }
  318. }
  319. else
  320. {
  321. _frame++;
  322. if (_frame > _frameCount - 1)
  323. {
  324. _frame = 0;
  325. _repeatedCount++;
  326. }
  327. }
  328. if (_status == 1) //new loop
  329. {
  330. _frame = _start;
  331. _frameElapsed = 0;
  332. _status = 0;
  333. DrawFrame();
  334. }
  335. else if (_status == 2) //ending
  336. {
  337. _frame = _endAt;
  338. _frameElapsed = 0;
  339. _status = 3; //ended
  340. DrawFrame();
  341. DispatchEvent("onPlayEnd", null);
  342. }
  343. else
  344. {
  345. DrawFrame();
  346. if (_frame == _end)
  347. {
  348. if (_times > 0)
  349. {
  350. _times--;
  351. if (_times == 0)
  352. _status = 2; //ending
  353. else
  354. _status = 1; //new loop
  355. }
  356. else if (_start != 0)
  357. _status = 1; //new loop
  358. }
  359. }
  360. }
  361. void DrawFrame()
  362. {
  363. if (_frameCount > 0)
  364. {
  365. Frame frame = _frames[_frame];
  366. graphics.texture = frame.texture;
  367. }
  368. }
  369. }
  370. }