AnimePlayer.cs 32 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808
  1. /**
  2. * 魔力宝贝图档解析脚本 - CGTool
  3. *
  4. * @Author HonorLee (dev@honorlee.me)
  5. * @Version 1.0 (2023-04-15)
  6. * @License GPL-3.0
  7. *
  8. * AnimePlayer.cs 动画播放器-挂载类
  9. */
  10. using System;
  11. using System.Collections.Generic;
  12. using UnityEngine;
  13. using UnityEngine.EventSystems;
  14. using UnityEngine.UIElements;
  15. using Image = UnityEngine.UI.Image;
  16. namespace CrossgateToolkit
  17. {
  18. //动画周期回调
  19. public delegate void AnimeCallback(Anime.ActionType actionType);
  20. //动画动作帧监听
  21. public delegate void AnimeEffectListener(Anime.EffectType effect);
  22. //动画音频帧监听
  23. public delegate void AnimeAudioListener(int audioIndex);
  24. public enum MouseType
  25. {
  26. Enter,
  27. Exit,
  28. Click
  29. }
  30. //鼠标移入事件监听
  31. public delegate void MouseListener(MouseType mouseType);
  32. /**
  33. * 动画播放器,用于播放CG动画,支持多动画队列播放
  34. * 脚本需绑定至挂载了SpriteRenderer、Image和RectTransform的对象上
  35. * ########除此之外,还需绑定BoxCollider2D(可选),用于监听鼠标的移入移出事件#####此条删除
  36. *
  37. * 当动画播放完成后会自动调用onFinishCallback回调函数
  38. * 另外可指定onActionListener和onAudioListener监听动画动作帧和音频帧
  39. * 目前已知的动作帧有:
  40. * 击中 伤害结算
  41. */
  42. public class AnimePlayer : MonoBehaviour,IPointerEnterHandler,IPointerExitHandler,IPointerClickHandler
  43. {
  44. //动画帧数据
  45. private class AnimeFrame
  46. {
  47. public int Index;
  48. public GraphicInfoData GraphicInfo;
  49. public Sprite Sprite;
  50. public AnimeFrameInfo AnimeFrameInfo;
  51. }
  52. //播放配置数据
  53. private class AnimeOption
  54. {
  55. public uint AnimeSerial;
  56. public Anime.DirectionType Direction;
  57. public Anime.ActionType actionType;
  58. public Anime.PlayType playType;
  59. public float Speed;
  60. public float FrameRate;
  61. public AnimeDetail AnimeDetail;
  62. public AnimeCallback onFinishCallback;
  63. public AnimeEffectListener onEffectListener;
  64. public int CurrentFrame = 0;
  65. public bool KeepFrame = false;
  66. public bool _effectOverCalled = false;
  67. public bool _finishedCalled = false;
  68. public bool _keepCallback = false;
  69. }
  70. //当前播放
  71. private uint _currentSerial;
  72. private AnimeOption _currentAnime = null;
  73. private AnimeFrame[] _frames;
  74. // private int _currentFrame;
  75. //是否播放
  76. private bool isPlayable;
  77. // private bool isPlayable
  78. // {
  79. // get => _isPlayable;
  80. // set
  81. // {
  82. // _isPlayable = value;
  83. // if (_isPlayable)
  84. // {
  85. // _timer = Time.time * 1000;
  86. // }
  87. // else
  88. // {
  89. // Debug.Log("set isPlayable " + isPlayable + " "+_currentAnime?.actionType);
  90. // }
  91. // }
  92. // }
  93. //待播放队列
  94. private readonly List<AnimeOption> _animeQueue = new List<AnimeOption>(10);
  95. //计时器
  96. private float _timer;
  97. //下一帧延迟
  98. private float _delay;
  99. //绑定渲染对象
  100. [SerializeField,Header("Image渲染")] public bool isRenderByImage = false;
  101. [SerializeField,Header("序列帧合批")] public bool isFrameBatch = false;
  102. [SerializeField, Header("合批压缩")] public bool isBatchCompress;
  103. [SerializeField,Header("线性过滤")] public bool isLinearFilter = false;
  104. [SerializeField,Header("PPU100模式")] public bool isPPU100 = false;
  105. [Header("序列帧Texture")] public Texture2D frameTexture;
  106. private SpriteRenderer _spriteRenderer;
  107. private Image _imageRenderer;
  108. private int _paletIndex = 0;
  109. public int PaletIndex
  110. {
  111. get { return _paletIndex; }
  112. set
  113. {
  114. _paletIndex = value;
  115. if (_currentAnime != null && value != _paletIndex)
  116. {
  117. _play();
  118. }
  119. }
  120. }
  121. //绑定RectTransform
  122. private RectTransform _rectTransform;
  123. //动画动作帧监听
  124. // public AnimeEffectListener onEffectListener;
  125. public AnimeAudioListener onAudioListener;
  126. //鼠标事件监听
  127. public MouseListener onMouseListener;
  128. //获取偏移量(无用)
  129. public Vector2 offset
  130. {
  131. get
  132. {
  133. float offsetX = -_frames[_currentAnime.CurrentFrame].AnimeFrameInfo.OffsetX;
  134. float offsetY = _frames[_currentAnime.CurrentFrame].AnimeFrameInfo.OffsetY;
  135. return new Vector2(offsetX, offsetY);
  136. }
  137. }
  138. //实例初始化时获取相关绑定
  139. private void Awake()
  140. {
  141. //调整渲染
  142. _imageRenderer = GetComponent<Image>();
  143. _spriteRenderer = GetComponent<SpriteRenderer>();
  144. _rectTransform = GetComponent<RectTransform>();
  145. if(_imageRenderer == null) _imageRenderer = gameObject.AddComponent<Image>();
  146. if(_spriteRenderer == null) _spriteRenderer = gameObject.AddComponent<SpriteRenderer>();
  147. if(_rectTransform == null) _rectTransform = gameObject.AddComponent<RectTransform>();
  148. gameObject.SetActive(false);
  149. }
  150. private void Start()
  151. {
  152. _updateRenderMode();
  153. }
  154. private void OnDisable()
  155. {
  156. // 被隐藏后及时清理数据
  157. // Stop();
  158. Pause();
  159. }
  160. private void OnEnable()
  161. {
  162. if(_currentAnime!=null) Resume();
  163. }
  164. // 使用Image模式渲染
  165. public bool RenderByImage
  166. {
  167. get => isRenderByImage;
  168. set
  169. {
  170. isRenderByImage = value;
  171. _updateRenderMode();
  172. }
  173. }
  174. // 设置当前播放序列,默认方向North,动作Stand,播放类型Loop,播放速度1f
  175. public uint Serial
  176. {
  177. get => _currentSerial;
  178. set
  179. {
  180. if (value == 0)
  181. {
  182. Stop();
  183. return;
  184. }
  185. Anime.DirectionType direction =
  186. _currentAnime?.Direction ?? Anime.DirectionType.North;
  187. Anime.ActionType actionType = _currentAnime?.actionType ?? Anime.ActionType.Idle;
  188. Anime.PlayType playType = _currentAnime?.playType ?? Anime.PlayType.Loop;
  189. float speed = _currentAnime?.Speed ?? 1f;
  190. AnimeCallback onFinishCallback = _currentAnime?.onFinishCallback;
  191. AnimeEffectListener onEffectListener = _currentAnime?.onEffectListener;
  192. play(value, direction, actionType, playType, speed, onEffectListener,onFinishCallback);
  193. }
  194. }
  195. // 动态调整播放类型
  196. public Anime.PlayType PlayType
  197. {
  198. get => _currentAnime?.playType ?? Anime.PlayType.Loop;
  199. set
  200. {
  201. if (_currentAnime != null)
  202. {
  203. _currentAnime.playType = value;
  204. }
  205. }
  206. }
  207. // 动态调整播放回调
  208. public AnimeCallback OnFinishCallback
  209. {
  210. get => _currentAnime?.onFinishCallback;
  211. set
  212. {
  213. if (_currentAnime != null)
  214. {
  215. _currentAnime.onFinishCallback = value;
  216. }
  217. }
  218. }
  219. public AnimeCallback OnCycleCallback;
  220. // 更新渲染模式
  221. private void _updateRenderMode()
  222. {
  223. if (isRenderByImage)
  224. {
  225. _imageRenderer.enabled = true;
  226. _spriteRenderer.enabled = false;
  227. }
  228. else
  229. {
  230. _imageRenderer.enabled = false;
  231. _spriteRenderer.enabled = true;
  232. }
  233. }
  234. /// <summary>
  235. /// 播放动画。调用此方法将会清空当前播放队列,调用完成可通过链式调用 <c>nextPlay</c> 方法添加动画到播放队列。
  236. /// </summary>
  237. /// <param name="Serial">动画序列号</param>
  238. /// <param name="Direction">动画方向</param>
  239. /// <param name="ActionType">动画动作</param>
  240. /// <param name="PlayType">播放类型</param>
  241. /// <param name="Speed">播放速度,以 1s 为基准,根据动画帧率计算实际播放周期时长</param>
  242. /// <param name="onEffectListener">动画动作帧监听</param>
  243. /// <param name="onFinishCallback">动画结束回调</param>
  244. /// <returns>AnimePlayer</returns>
  245. public AnimePlayer play(uint serial, Anime.DirectionType Direction = Anime.DirectionType.North,
  246. Anime.ActionType actionType = Anime.ActionType.Idle, Anime.PlayType playType = Anime.PlayType.Once,
  247. float Speed = 1f,AnimeEffectListener onEffectListener = null,AnimeCallback onFinishCallback = null,bool keepCallback = false)
  248. {
  249. AnimeOption animeOption = CreateAnimeOption(serial, Direction, actionType, playType, Speed,onEffectListener, onFinishCallback,keepCallback);
  250. if (animeOption == null)
  251. {
  252. onFinishCallback?.Invoke(actionType);
  253. // Debug.Log("AnimePlayer:AnimeOption create failed");
  254. return this;
  255. }
  256. if (_currentAnime!=null && _currentAnime._keepCallback && isPlayable)
  257. {
  258. Pause();
  259. if(!_currentAnime._effectOverCalled) _currentAnime.onEffectListener?.Invoke(Anime.EffectType.HitOver);
  260. if(!_currentAnime._finishedCalled) _currentAnime.onFinishCallback?.Invoke(_currentAnime.actionType);
  261. }
  262. //清空播放队列
  263. _animeQueue.Clear();
  264. _animeQueue.Add(animeOption);
  265. _currentAnime = null;
  266. _play();
  267. //链式调用,后续可通过nextPlay方法添加动画到播放队列
  268. return this;
  269. }
  270. //播放动画
  271. public AnimePlayer play(uint serial, Anime.PlayType playType, float speed = 1f,AnimeEffectListener onEffectListener = null,AnimeCallback onFinishCallback = null,bool keepCallback = false)
  272. {
  273. return play(serial,Anime.DirectionType.North,Anime.ActionType.Idle,playType,speed,onEffectListener,onFinishCallback,keepCallback);
  274. }
  275. //不改变Serial情况下播放动画
  276. public AnimePlayer play(Anime.DirectionType directionType,Anime.ActionType actionType,Anime.PlayType playType,float Speed=1f,AnimeEffectListener onEffectListener=null,AnimeCallback onFinishCallback=null,bool keepCallback = false)
  277. {
  278. return play(_currentSerial, directionType, actionType, playType,
  279. Speed,onEffectListener, onFinishCallback,keepCallback);
  280. }
  281. //播放一次
  282. public AnimePlayer playOnce(Anime.DirectionType directionType,Anime.ActionType actionType,float Speed=1f,AnimeEffectListener onEffectListener=null,AnimeCallback onFinishCallback=null,bool keepCallback = false)
  283. {
  284. return play(_currentSerial, directionType, actionType, Anime.PlayType.Once,
  285. Speed, onEffectListener,onFinishCallback,keepCallback);
  286. }
  287. //播放循环
  288. public AnimePlayer playLoop(Anime.DirectionType directionType,Anime.ActionType actionType,float Speed=1f,AnimeEffectListener onEffectListener=null,AnimeCallback onFinishCallback=null,bool keepCallback = false)
  289. {
  290. return play(_currentSerial, directionType, actionType, Anime.PlayType.Loop,
  291. Speed, onEffectListener,onFinishCallback,keepCallback);
  292. }
  293. //调整动画方向
  294. public void changeDirection(Anime.DirectionType directionType)
  295. {
  296. if (directionType == _currentAnime.Direction || directionType == Anime.DirectionType.NULL) return;
  297. // _currentAnime = CreateAnimeOption(_currentAnime.AnimeSerial, directionType, _currentAnime.actionType,
  298. // _currentAnime.playType, _currentAnime.Speed, _currentAnime.onEffectListener,_currentAnime.onFinishCallback);
  299. AnimeOption animeOption = CreateAnimeOption(_currentAnime.AnimeSerial, directionType, _currentAnime.actionType,
  300. _currentAnime.playType, _currentAnime.Speed);
  301. _currentAnime = CreateAnimeOption(_currentAnime.AnimeSerial, directionType, _currentAnime.actionType,
  302. _currentAnime.playType, _currentAnime.Speed);
  303. if (animeOption == null) return;
  304. _currentAnime = animeOption;
  305. if(_animeQueue.Count>0) _animeQueue[0] = _currentAnime;
  306. else _animeQueue.Add(_currentAnime);
  307. _play();
  308. }
  309. public Anime.DirectionType DirectionType
  310. {
  311. get => _currentAnime?.Direction ?? Anime.DirectionType.NULL;
  312. set
  313. {
  314. if (_currentAnime != null)
  315. {
  316. changeDirection(value);
  317. }
  318. }
  319. }
  320. public void Rotate(bool clockwise = true)
  321. {
  322. if (_currentAnime == null) return;
  323. int direction = (int)_currentAnime.Direction;
  324. if (clockwise)
  325. {
  326. direction += 1;
  327. if(direction>7) direction = 0;
  328. }
  329. else
  330. {
  331. direction -= 1;
  332. if(direction<0) direction = 7;
  333. }
  334. changeDirection((Anime.DirectionType)direction);
  335. }
  336. //调整动画动作类型
  337. public void changeActionType(Anime.ActionType actionType)
  338. {
  339. if (actionType == _currentAnime.actionType) return;
  340. // _currentAnime = CreateAnimeOption(_currentAnime.AnimeSerial, _currentAnime.Direction,actionType,
  341. // _currentAnime.playType, _currentAnime.Speed, _currentAnime.onEffectListener,_currentAnime.onFinishCallback);
  342. AnimeOption animeOption = CreateAnimeOption(_currentAnime.AnimeSerial, _currentAnime.Direction,actionType,
  343. _currentAnime.playType, _currentAnime.Speed);
  344. if (animeOption == null) return;
  345. _currentAnime = animeOption;
  346. if(_animeQueue.Count>0) _animeQueue[0] = _currentAnime;
  347. else _animeQueue.Add(_currentAnime);
  348. _play();
  349. }
  350. public Anime.ActionType ActionType
  351. {
  352. get => _currentAnime?.actionType ?? Anime.ActionType.NULL;
  353. set
  354. {
  355. if (_currentAnime != null)
  356. {
  357. changeActionType(value);
  358. }
  359. }
  360. }
  361. //播放
  362. private void _play()
  363. {
  364. isPlayable = false;
  365. _currentAnime = null;
  366. AnimeOption animeOption = _animeQueue[0];
  367. // Debug.Log("AnimePlayer:play " + animeOption.AnimeSerial + " " + animeOption.actionType);
  368. AnimeFrame[] frames = new AnimeFrame[animeOption.AnimeDetail.FrameCount];
  369. if (isFrameBatch)
  370. {
  371. Anime.BakeAnimeFrames(animeOption.AnimeDetail, _paletIndex, isLinearFilter, isBatchCompress);
  372. //获取动画帧数据
  373. for (int i = 0; i < animeOption.AnimeDetail.AnimeFrameInfos.Count; i++)
  374. {
  375. if(!animeOption.AnimeDetail.AnimeFrameInfos[i].AnimeSprites.ContainsKey(_paletIndex)) continue;
  376. if(animeOption.AnimeDetail.AnimeFrameInfos[i].AnimeSprites[_paletIndex] == null) continue;
  377. //创建帧数据
  378. frames[i] = new AnimeFrame();
  379. frames[i].Index = i;
  380. frames[i].GraphicInfo = animeOption.AnimeDetail.AnimeFrameInfos[i].GraphicInfo;
  381. GraphicDetail graphicDetail =
  382. animeOption.AnimeDetail.AnimeFrameInfos[i].AnimeSprites[_paletIndex][isLinearFilter];
  383. frames[i].Sprite = isPPU100 ? graphicDetail.SpritePPU100 : graphicDetail.Sprite;
  384. frames[i].AnimeFrameInfo = animeOption.AnimeDetail.AnimeFrameInfos[i];
  385. }
  386. }
  387. else
  388. {
  389. //获取动画帧数据
  390. for (int i = 0; i < animeOption.AnimeDetail.AnimeFrameInfos.Count; i++)
  391. {
  392. AnimeFrameInfo animeFrameInfo = animeOption.AnimeDetail.AnimeFrameInfos[i];
  393. GraphicInfoData graphicInfoData = GraphicInfo.GetGraphicInfoDataByIndex(
  394. animeOption.AnimeDetail.Version, animeOption.AnimeDetail.AnimeFrameInfos[i].GraphicIndex);
  395. if (graphicInfoData == null)
  396. {
  397. Debug.Log("GraphicInfo Serial:" +
  398. animeOption.AnimeDetail.AnimeFrameInfos[i].GraphicIndex + " is null");
  399. continue;
  400. }
  401. int subPaletIndex = -1;
  402. if (animeOption.AnimeDetail.IsHighVersion) subPaletIndex = (int)animeOption.AnimeDetail.Serial;
  403. GraphicDetail graphicData =
  404. GraphicData.GetGraphicDetail(graphicInfoData, _paletIndex, subPaletIndex, isLinearFilter);
  405. if (graphicData == null)
  406. {
  407. Debug.Log("GraphicData Serial:" +
  408. animeOption.AnimeDetail.AnimeFrameInfos[i].GraphicIndex + " is null");
  409. continue;
  410. }
  411. //创建帧数据
  412. frames[i] = new AnimeFrame();
  413. frames[i].Index = i;
  414. frames[i].GraphicInfo = graphicInfoData;
  415. frames[i].Sprite = isPPU100 ? graphicData.SpritePPU100 : graphicData.Sprite;
  416. frames[i].AnimeFrameInfo = animeFrameInfo;
  417. }
  418. }
  419. _currentAnime = animeOption;
  420. _currentSerial = animeOption.AnimeSerial;
  421. _frames = frames;
  422. // _currentAnime.CurrentFrame = _currentAnime.CurrentFrame;
  423. _delay = 0;
  424. gameObject.SetActive(true);
  425. isPlayable = true;
  426. UpdateFrame();
  427. }
  428. //播放延时
  429. public void DelayPlay(float delayTime)
  430. {
  431. _delay = delayTime*1000;
  432. }
  433. // 设置速度
  434. public void SetSpeed(float speed)
  435. {
  436. if (_currentAnime == null) return;
  437. _currentAnime.Speed = speed;
  438. _currentAnime.FrameRate =
  439. _currentAnime.AnimeDetail.CycleTime * 1f / speed / _currentAnime.AnimeDetail.FrameCount;
  440. }
  441. //停止播放
  442. public void Stop()
  443. {
  444. isPlayable = false;
  445. _currentAnime = null;
  446. _frames = null;
  447. gameObject.SetActive(false);
  448. //清理缓存
  449. if(_imageRenderer!=null) _imageRenderer.sprite = null;
  450. if(_spriteRenderer!=null) _spriteRenderer.sprite = null;
  451. }
  452. //暂停播放
  453. public void Pause()
  454. {
  455. isPlayable = false;
  456. }
  457. // 恢复播放
  458. public void Play()
  459. {
  460. if(_currentAnime!=null) isPlayable = true;
  461. }
  462. //恢复播放
  463. public void Resume()
  464. {
  465. isPlayable = true;
  466. }
  467. //修改播放类型---重复方法--考虑删掉
  468. public void ChangePlayType(Anime.PlayType playType)
  469. {
  470. if (_currentAnime == null) return;
  471. _currentAnime.playType = playType;
  472. }
  473. //创建动画配置
  474. private AnimeOption CreateAnimeOption(uint serial, Anime.DirectionType Direction, Anime.ActionType actionType,
  475. Anime.PlayType playType=Anime.PlayType.Once, float Speed = 1f,AnimeEffectListener onEffectListener = null, AnimeCallback onFinishCallback = null,bool keepCallback = false)
  476. {
  477. AnimeDetail animeDetail = Anime.GetAnimeDetail(serial, Direction, actionType);
  478. if (animeDetail == null)
  479. {
  480. // 动画不存在,尝试查找图档
  481. GraphicInfoData graphicInfoData = GraphicInfo.GetGraphicInfoData(serial);
  482. if (graphicInfoData != null)
  483. {
  484. // 图档存在情况下,不创建动画,直接更新图像显示并返回
  485. GraphicDetail graphicDetail = GraphicData.GetGraphicDetail(graphicInfoData, _paletIndex, 0, isLinearFilter);
  486. if (graphicDetail != null)
  487. {
  488. if (isRenderByImage)
  489. {
  490. _imageRenderer.sprite = isPPU100 ? graphicDetail.SpritePPU100 : graphicDetail.Sprite;
  491. _imageRenderer.SetNativeSize();
  492. }
  493. else
  494. {
  495. _spriteRenderer.sprite = isPPU100 ? graphicDetail.SpritePPU100 : graphicDetail.Sprite;
  496. }
  497. _rectTransform.sizeDelta = new Vector2(graphicDetail.Sprite.rect.width, graphicDetail.Sprite.rect.height);
  498. gameObject.SetActive(true);
  499. return null;
  500. }
  501. }
  502. else
  503. {
  504. return null;
  505. }
  506. // Debug.Log("AnimePlayer:AnimeDetail [" + serial + "] is null");
  507. }
  508. AnimeOption animeOption = new AnimeOption()
  509. {
  510. AnimeSerial = serial,
  511. Direction = Direction,
  512. actionType = actionType,
  513. playType = playType,
  514. Speed = Speed,
  515. FrameRate = animeDetail.CycleTime * 1f / (float)animeDetail.FrameCount /Speed,
  516. AnimeDetail = animeDetail,
  517. onEffectListener = onEffectListener,
  518. onFinishCallback = onFinishCallback,
  519. _keepCallback = keepCallback
  520. };
  521. // Debug.Log("AnimePlayer:CreateAnimeOption " + animeOption.AnimeSerial + " " + animeOption.actionType +" speed:"+Speed+" framerate:"+animeOption.FrameRate);
  522. return animeOption;
  523. }
  524. //加入链式动画播放队列
  525. public AnimePlayer nextPlay(uint serial, Anime.DirectionType Direction, Anime.ActionType actionType,
  526. Anime.PlayType playType=Anime.PlayType.Once, float Speed = 1f, AnimeEffectListener onEffectListener=null, AnimeCallback onFinishCallback = null)
  527. {
  528. AnimeOption animeOption = CreateAnimeOption(serial, Direction, actionType, playType, Speed, onEffectListener,onFinishCallback);
  529. if (animeOption == null)
  530. {
  531. onFinishCallback?.Invoke(actionType);
  532. return this;
  533. }
  534. _animeQueue.Add(animeOption);
  535. if (_animeQueue[0] == animeOption)
  536. {
  537. _play();
  538. }
  539. return this;
  540. }
  541. //加入链式动画播放队列
  542. public AnimePlayer nextPlay(Anime.DirectionType Direction, Anime.ActionType actionType,
  543. Anime.PlayType playType=Anime.PlayType.Once, float Speed = 1f, AnimeEffectListener onEffectListener=null, AnimeCallback onFinishCallback = null)
  544. {
  545. return nextPlay(_currentSerial, Direction, actionType, playType, Speed, onEffectListener, onFinishCallback);
  546. }
  547. // 保持当前帧并切换动画方向(特殊情况如被暴击或击飞后保持受伤帧旋转)
  548. public void changeDirectionKeepFrame(Anime.DirectionType directionType)
  549. {
  550. if (directionType == _currentAnime.Direction || directionType == Anime.DirectionType.NULL) return;
  551. int currentFrame = _currentAnime.CurrentFrame;
  552. // _currentAnime = CreateAnimeOption(_currentAnime.AnimeSerial, directionType, _currentAnime.actionType,
  553. // _currentAnime.playType, _currentAnime.Speed, _currentAnime.onEffectListener,_currentAnime.onFinishCallback);
  554. AnimeOption animeOption = CreateAnimeOption(_currentAnime.AnimeSerial, directionType, _currentAnime.actionType,
  555. _currentAnime.playType, _currentAnime.Speed);
  556. if (animeOption == null) return;
  557. animeOption.CurrentFrame = --currentFrame;
  558. animeOption.KeepFrame = true;
  559. if(_animeQueue.Count>0) _animeQueue[0] = animeOption;
  560. else _animeQueue.Add(animeOption);
  561. _play();
  562. }
  563. //更新计算
  564. private void Update()
  565. {
  566. if (!isPlayable || _currentAnime==null) return;
  567. float now = Time.time * 1000;
  568. if ((now - _timer - _delay) >= _currentAnime.FrameRate) UpdateFrame();
  569. }
  570. //更新帧
  571. private void UpdateFrame()
  572. {
  573. _delay = 0;
  574. AnimeOption playingAnime = _currentAnime;
  575. if (!isPlayable || _frames.Length == 0) return;
  576. //动画结束
  577. if (playingAnime.CurrentFrame >= playingAnime.AnimeDetail.FrameCount)
  578. {
  579. OnCycleCallback?.Invoke(playingAnime.actionType);
  580. //循环播放
  581. if (playingAnime.playType == Anime.PlayType.Loop)
  582. {
  583. if(playingAnime==_currentAnime) playingAnime.onFinishCallback?.Invoke(playingAnime.actionType);
  584. playingAnime._finishedCalled = true;
  585. playingAnime.CurrentFrame = 0;
  586. }else if (playingAnime.playType is Anime.PlayType.Once or Anime.PlayType.OnceAndDestroy)
  587. {
  588. if (playingAnime.playType == Anime.PlayType.OnceAndDestroy)
  589. {
  590. _animeQueue.Clear();
  591. _spriteRenderer.sprite = null;
  592. _imageRenderer.sprite = null;
  593. _rectTransform.sizeDelta = Vector2.zero;
  594. if(playingAnime==_currentAnime) playingAnime.onFinishCallback?.Invoke(playingAnime.actionType);
  595. gameObject.SetActive(false);
  596. return;
  597. }
  598. if (playingAnime.KeepFrame)
  599. {
  600. if(playingAnime==_currentAnime) playingAnime.onFinishCallback?.Invoke(playingAnime.actionType);
  601. playingAnime.CurrentFrame--;
  602. }
  603. else
  604. {
  605. _animeQueue.RemoveAt(0);
  606. //播放下一个动画
  607. if (_animeQueue.Count > 0)
  608. {
  609. AnimeCallback callback = playingAnime.onFinishCallback;
  610. Anime.ActionType actionType = playingAnime.actionType;
  611. // playingAnime.onFinishCallback?.Invoke(playingAnime.actionType);
  612. _play();
  613. callback?.Invoke(actionType);
  614. return;
  615. }
  616. else
  617. {
  618. Pause();
  619. // 回调在Pause之后避免时序问题导致影响下一个动画
  620. playingAnime.onFinishCallback?.Invoke(playingAnime.actionType);
  621. return;
  622. }
  623. }
  624. }
  625. }
  626. //问题帧自动跳过
  627. if (playingAnime.CurrentFrame < _frames.Length && _frames[playingAnime.CurrentFrame] == null)
  628. {
  629. playingAnime.CurrentFrame++;
  630. return;
  631. }
  632. //根据当前帧Sprite动态调整对象大小
  633. float width = _frames[playingAnime.CurrentFrame].Sprite.rect.width * 1f;
  634. float height = _frames[playingAnime.CurrentFrame].Sprite.rect.height * 1f;
  635. if (isPPU100)
  636. {
  637. width = width / 100f;
  638. height = height / 100f;
  639. }
  640. Vector3 pos = Vector3.zero;
  641. pos.x = _frames[playingAnime.CurrentFrame].GraphicInfo.OffsetX;
  642. pos.y = -_frames[playingAnime.CurrentFrame].GraphicInfo.OffsetY;
  643. if (isRenderByImage)
  644. {
  645. _imageRenderer.sprite = _frames[playingAnime.CurrentFrame].Sprite;
  646. _imageRenderer.SetNativeSize();
  647. if (playingAnime.AnimeDetail.FLAG.HasFlag(AnimeFlag.REVERSE_X) || playingAnime.AnimeDetail.FLAG.HasFlag(AnimeFlag.REVERSE_Y))
  648. {
  649. if (playingAnime.AnimeDetail.FLAG.HasFlag(AnimeFlag.REVERSE_X))
  650. {
  651. _imageRenderer.transform.localScale = new Vector3(-1, 1, 1);
  652. pos.x = -pos.x;
  653. }
  654. if (playingAnime.AnimeDetail.FLAG.HasFlag(AnimeFlag.REVERSE_Y))
  655. {
  656. _imageRenderer.transform.localScale = new Vector3(1, -1, 1);
  657. pos.y = -pos.y;
  658. }
  659. }
  660. else
  661. {
  662. _imageRenderer.transform.localScale = new Vector3(1, 1, 1);
  663. }
  664. _rectTransform.localPosition = pos;
  665. _rectTransform.pivot = new Vector2(0f,1f);
  666. }
  667. else
  668. {
  669. _spriteRenderer.sprite = _frames[playingAnime.CurrentFrame].Sprite;
  670. _rectTransform.sizeDelta = new Vector2(width, height);
  671. _spriteRenderer.size = new Vector2(width, height);
  672. _rectTransform.pivot = new Vector2(0.5f,0f);
  673. // Vector3 scale = isPPU100 ? new Vector3(100f, 100f, 100f) : Vector3.one;
  674. // _rectTransform.localScale = scale;
  675. if (playingAnime.AnimeDetail.FLAG.HasFlag(AnimeFlag.REVERSE_X) || playingAnime.AnimeDetail.FLAG.HasFlag(AnimeFlag.REVERSE_Y))
  676. {
  677. if (playingAnime.AnimeDetail.FLAG.HasFlag(AnimeFlag.REVERSE_X))
  678. {
  679. _spriteRenderer.flipX = true;
  680. }else
  681. {
  682. _spriteRenderer.flipX = false;
  683. }
  684. if (playingAnime.AnimeDetail.FLAG.HasFlag(AnimeFlag.REVERSE_Y))
  685. {
  686. _spriteRenderer.flipY = true;
  687. }else
  688. {
  689. _spriteRenderer.flipY = false;
  690. }
  691. }
  692. else
  693. {
  694. _spriteRenderer.flipX = false;
  695. _spriteRenderer.flipY = false;
  696. }
  697. _rectTransform.localPosition = Vector3.zero;
  698. }
  699. frameTexture = _frames[playingAnime.CurrentFrame].Sprite.texture;
  700. _timer = Time.time * 1000;
  701. //动画事件帧监听
  702. if (playingAnime==_currentAnime && _frames[playingAnime.CurrentFrame].AnimeFrameInfo.Effect > 0)
  703. playingAnime.onEffectListener?.Invoke(_frames[playingAnime.CurrentFrame].AnimeFrameInfo.Effect);
  704. if (playingAnime==_currentAnime && _frames[playingAnime.CurrentFrame].AnimeFrameInfo.Effect == Anime.EffectType.HitOver)
  705. playingAnime._effectOverCalled = true;
  706. //音频事件帧监听
  707. if (playingAnime==_currentAnime && _frames[playingAnime.CurrentFrame].AnimeFrameInfo.AudioIndex > 0)
  708. onAudioListener?.Invoke(_frames[playingAnime.CurrentFrame].AnimeFrameInfo.AudioIndex);
  709. playingAnime.CurrentFrame++;
  710. }
  711. public void OnPointerEnter(PointerEventData eventData)
  712. {
  713. onMouseListener?.Invoke(MouseType.Enter);
  714. }
  715. public void OnPointerExit(PointerEventData eventData)
  716. {
  717. onMouseListener?.Invoke(MouseType.Exit);
  718. }
  719. public void OnPointerClick(PointerEventData eventData)
  720. {
  721. onMouseListener?.Invoke(MouseType.Click);
  722. }
  723. }
  724. }