MovieOfFrames.cs 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233
  1. using System;
  2. using System.Collections;
  3. using System.Collections.Generic;
  4. using System.Linq;
  5. using System.Text.RegularExpressions;
  6. using UnityEngine;
  7. using UnityEngine.Events;
  8. using UnityEngine.UI;
  9. public sealed class MovieOfFrames : MonoBehaviour
  10. {
  11. /// <summary>
  12. /// 类型
  13. /// </summary>
  14. public enum Style
  15. {
  16. /// <summary>
  17. /// 循环
  18. /// </summary>
  19. Loop = 0,
  20. /// <summary>
  21. /// 乒乓
  22. /// </summary>
  23. PingPong = 1,
  24. /// <summary>
  25. /// 单次
  26. /// </summary>
  27. Once = 2
  28. }
  29. [SerializeField]
  30. bool m_PlayOnAwake = false;
  31. [SerializeField]
  32. int m_CurrentFrame = 0;
  33. [SerializeField]
  34. int m_FrameRate = 25;
  35. [SerializeField]
  36. Style m_Style = Style.Once;
  37. [SerializeField]
  38. float m_Space = 0;
  39. [SerializeField]
  40. List<Texture2D> m_Frames = new List<Texture2D>();
  41. [SerializeField]
  42. RawImage mRawImage = null;
  43. bool m_IsPlaying = false;
  44. /// <summary>
  45. /// 播放类型
  46. /// </summary>
  47. public Style style {
  48. get {
  49. return m_Style;
  50. }
  51. set {
  52. m_Style = value;
  53. }
  54. }
  55. /// <summary>
  56. /// 播放中?
  57. /// </summary>
  58. public bool isPlaying {
  59. get {
  60. return m_IsPlaying;
  61. }
  62. }
  63. /// <summary>
  64. /// 循环
  65. /// </summary>
  66. public bool loop {
  67. get {
  68. return style == Style.Loop;
  69. }
  70. set {
  71. if (value)
  72. style = Style.Loop;
  73. else
  74. style = Style.Once;
  75. }
  76. }
  77. public float space {
  78. get {
  79. return m_Space;
  80. }
  81. set {
  82. m_Space = value;
  83. }
  84. }
  85. /// <summary>
  86. /// 当前显示画面
  87. /// </summary>
  88. public Texture texture {
  89. get {
  90. return m_Frames[m_CurrentFrame];
  91. }
  92. }
  93. /// <summary>
  94. /// 总帧数
  95. /// </summary>
  96. public int maxFrames {
  97. get {
  98. return m_Frames.Count - 1;
  99. }
  100. }
  101. /// <summary>
  102. /// 当前帧数
  103. /// </summary>
  104. public int currentFrame {
  105. get {
  106. return m_CurrentFrame;
  107. }
  108. set {
  109. value = Mathf.Clamp(value, 0, maxFrames);
  110. m_CurrentFrame = value;
  111. Sample();
  112. }
  113. }
  114. /// <summary>
  115. /// 帧速率
  116. /// </summary>
  117. public int frameRate {
  118. get {
  119. return m_FrameRate;
  120. }
  121. }
  122. /// <summary>
  123. /// 起始是否播放
  124. /// </summary>
  125. public bool playOnAwake {
  126. get {
  127. return m_PlayOnAwake;
  128. }
  129. set {
  130. m_PlayOnAwake = value;
  131. }
  132. }
  133. /// <summary>
  134. /// 序列集合
  135. /// </summary>
  136. public Texture2D[] frames {
  137. get {
  138. return m_Frames.ToArray();
  139. }
  140. set {
  141. Sample();
  142. Stop();
  143. }
  144. }
  145. /// <summary>
  146. /// 播放
  147. /// </summary>
  148. public void Play() {
  149. if (isPlaying)
  150. return;
  151. m_IsPlaying = true;
  152. m_CurrentFrame = 0;
  153. Sample();
  154. StartCoroutine("PlayMovie");
  155. }
  156. /// <summary>
  157. /// 停止
  158. /// </summary>
  159. public void Stop() {
  160. StopCoroutine("PlayMovie");
  161. if (m_IsPlaying) {
  162. m_IsPlaying = false;
  163. }
  164. }
  165. /// <summary>
  166. /// 采样(更新图片)
  167. /// </summary>
  168. public void Sample() {
  169. mRawImage.texture = texture;
  170. }
  171. void Awake() {
  172. m_Frames = m_Frames.Where(f => Regex.IsMatch(f.name, @"^\d+$")).OrderBy(f => int.Parse(f.name)).ToList();
  173. }
  174. void OnEnable() {
  175. if (m_PlayOnAwake)
  176. Play();
  177. }
  178. void OnDisable() {
  179. Stop();
  180. }
  181. IEnumerator PlayMovie() {
  182. bool flag = true;
  183. while (isPlaying) {
  184. float waitTime = 1f / m_FrameRate;
  185. switch (m_Style) {
  186. case Style.Loop:
  187. if (m_CurrentFrame == maxFrames) {
  188. m_CurrentFrame = 0;
  189. yield return new WaitForSeconds(space);
  190. }
  191. m_CurrentFrame++;
  192. break;
  193. case Style.PingPong:
  194. if (m_CurrentFrame == maxFrames) {
  195. flag = false;
  196. yield return new WaitForSeconds(space);
  197. }
  198. if (m_CurrentFrame == 0) {
  199. flag = true;
  200. yield return new WaitForSeconds(space);
  201. }
  202. if (flag) {
  203. m_CurrentFrame++;
  204. }
  205. else {
  206. m_CurrentFrame--;
  207. }
  208. break;
  209. case Style.Once:
  210. if (m_CurrentFrame == maxFrames) {
  211. m_IsPlaying = false;
  212. StopCoroutine("PlayMovie");
  213. }
  214. m_CurrentFrame++;
  215. break;
  216. }
  217. m_CurrentFrame = Mathf.Clamp(m_CurrentFrame, 0, maxFrames);
  218. Sample();
  219. yield return new WaitForSecondsRealtime(waitTime);
  220. }
  221. }
  222. }