//**********************************************// //作者:#杨全福# //日期:#2020.02.12# //简述:#帧动画脚本# //*********************************************// using Thousandto.Core.Asset; using Thousandto.Plugins.Common; using UnityEngine; namespace Thousandto.GameUI.Form { public class UIFrameAnimation : MonoCacheBase { #region//常量 private const string AtlasName = "UIAnimationAtlas"; #endregion #region//私有变量 //动画ID,对应Atlas的索引 private int _curAinmId = 0; //当前帧 private int _curFrame = 0; //帧率计时器 private float _frameTimer = 0f; //默认30帧 private int _frameRate = 30; //单帧时间 private float _oneFrameTime = 1f / 30; //使用的sprite private UISprite _targetSprite = null; //使用的atlas private UIAtlas _atlas = null; //帧数量 private int _frameCount = 0; //是否循环 private FrameAnimWrapMode _wrapMode = FrameAnimWrapMode.Once; #endregion #region//继承基类 private void OnEnable() { LoadAtlas(); } private void OnDisable() { UnLoadAtlas(); } private void OnDestroy() { UnLoadAtlas(); } private void Update() { if (_targetSprite == null || _curAinmId <= 0 || _atlas == null || _frameCount <= 0) return; _frameTimer -= Time.deltaTime; if(_frameTimer <= 0) { SetCurFrame(_curFrame + 1); } } #endregion #region//公有函数 //播放动画 public void PlayAnim(int animId, int frameRate, FrameAnimWrapMode wrapMode) { if (animId <= 0) return; if (frameRate <= 0) return; if(_targetSprite == null) _targetSprite = GetComponent(); if(_targetSprite == null) return; if (_curAinmId == animId) return; //先释放老的 UnLoadAtlas(); _curAinmId = animId; _frameRate = frameRate; _oneFrameTime = 1f / _frameRate; _frameTimer = 0f; _wrapMode = wrapMode; //在加载新的 LoadAtlas(); } //停止动画 public void StopAnim() { UnLoadAtlas(); } #endregion #region//私有函数 //设置当前帧 private void SetCurFrame(int frame) { _curFrame = frame; var useFrame = 0; switch(_wrapMode) { case FrameAnimWrapMode.Loop: useFrame = _curFrame % _frameCount; break; case FrameAnimWrapMode.PingPong: if((_curFrame / _frameCount) % 2 == 0) { useFrame = _curFrame % _frameCount; } else { useFrame = (_frameCount - 1) - (_curFrame % _frameCount); } break; default: useFrame = Mathf.Min(_curFrame, _frameCount - 1); break; } if (_frameTimer < 0) { _frameTimer = _oneFrameTime + _frameTimer; } else { _frameTimer = _oneFrameTime; } if (_targetSprite != null) { _targetSprite.spriteName = string.Format("{0}_{1}", _curAinmId, useFrame); } } //加载atlas private void LoadAtlas() { if(_targetSprite == null || _curAinmId <= 0) return; UIPoolAssetsLoader.LoadAtlasPrefabAsyn(AtlasName, _curAinmId, atlasTrans => { if (atlasTrans != null) { _atlas = atlasTrans.GetComponent(); if (null != _atlas) { _targetSprite.atlas = _atlas; _frameCount = _atlas.spriteList.Count; //从第0帧开始播放 SetCurFrame(0); } } }); } //释放atlas private void UnLoadAtlas() { if (_targetSprite == null || _curAinmId <= 0) return; _targetSprite.atlas = null; UIPoolAssetsLoader.UnloadAtlas(AtlasName, _curAinmId, _atlas.transform); _curAinmId = 0; _atlas = null; } #endregion } }