Files
Main/Assets/GameAssets/Resources/GameUI/Form/UIComponents/Scripts/UIFrameAnimation.cs

169 lines
4.8 KiB
C#
Raw Normal View History

2025-01-25 04:38:09 +08:00
//**********************************************//
//作者:#杨全福#
//日期:#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<UISprite>();
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<UIAtlas>();
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
}
}