Unity中实现播放2D序列帧特效(内存优化版)
原创
©著作权归作者所有:来自51CTO博客作者mb60e5417d375b8的原创作品,请联系作者获取转载授权,否则将追究法律责任
一:使用
二:实现
using UnityEngine;
using UnityEngine.UI;
using System;
using System.Collections.Generic;
/// <summary>
/// 2D序列帧特效
/// </summary>
public class UI_2DEffect : MonoBehaviour
{
private Image img;//图片组件
[Header("资源目录")]
public string resDir;
[Header("总帧数")]
[Space(25)]
public int totalFarme;
[Header("帧率")]
public int frameRate;
[Header("是否自动播放")]
[Space(25)]
public bool autoPlay = false;
[Header("是否循环播放")]
public bool isLoop = false;
private Sprite curSprite;//当前Sprite
private int curFrame;//当前帧
private float timer;//计时器
private bool isPlaying;//是否在播放
private Dictionary<int, Action> eventDict = new Dictionary<int, Action>();//存储事件的字典
#region Init
private void Awake()
{
img = GetComponent<Image>();
img.enabled = false;
}
private void Start()
{
if (autoPlay)
{
Play();
}
}
#endregion
#region Main
/// <summary>
/// 注册事件
/// </summary>
public void RegisterEvent(int eventFrame, Action onFinish)
{
if (!eventDict.ContainsKey(eventFrame))
{
eventDict.Add(eventFrame, onFinish);
}
}
/// <summary>
/// 播放
/// </summary>
public void Play()
{
timer = 1f / frameRate;
curFrame = 0;
curSprite = null;
img.enabled = true;
img.sprite = null;
isPlaying = true;
}
/// <summary>
/// 暂停
/// </summary>
public void Pause()
{
isPlaying = false;
}
/// <summary>
/// 继续
/// </summary>
public void Resume()
{
isPlaying = true;
}
/// <summary>
/// 停止
/// </summary>
public void Stop()
{
img.enabled = false;
isPlaying = false;
//清除结束的事件
ClearFinishEvent();
//卸载资源
Unload();
}
#endregion
#region Misc
/// <summary>
/// 检测事件
/// </summary>
private void CheckEvent()
{
int tempKey = -1;
foreach (var temp in eventDict)
{
if (curFrame == temp.Key)
{
tempKey = temp.Key;
eventDict[temp.Key]?.Invoke();
}
}
eventDict.Remove(tempKey);
}
/// <summary>
/// 检测播放
/// </summary>
private void CheckPlay()
{
if (isPlaying == false)
{
return;
}
timer += Time.fixedDeltaTime;
if (timer >= 1f / frameRate)
{
//播放下一帧
PlayNextFrame();
timer = 0;
}
}
/// <summary>
/// 播放下一帧
/// </summary>
private void PlayNextFrame()
{
if (curFrame >= totalFarme)
{
//停止
Stop();
if (isLoop)
{
Play();
}
return;
}
if (curSprite != null)
{
//卸载资源
Unload();
}
string path = resDir + "/" + curFrame;
curSprite = Resources.Load<Sprite>(path);
if (curSprite == null)
{
Debug.LogWarning("没有此图片:" + path);
}
else
{
img.sprite = curSprite;
curFrame++;
}
}
/// <summary>
/// 卸载资源
/// </summary>
private void Unload()
{
curSprite = null;
img.sprite = null;
Resources.UnloadUnusedAssets();
}
/// <summary>
/// 清除结束的事件
/// </summary>
private void ClearFinishEvent()
{
eventDict.Clear();
}
private void FixedUpdate()
{
//检测事件
CheckEvent();
//检测播放
CheckPlay();
}
#endregion
}
三:Resources.UnloadUnusedAssets的用法