news 2026/5/12 23:56:32

简单序列帧动画播放器,播放GIF

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
简单序列帧动画播放器,播放GIF

using UnityEngine;
using UnityEngine.UI;
using UnityEngine.U2D;

/// <summary>
/// 简单序列帧动画播放器
/// 支持直接拖入 SpriteAtlas 图集,自动提取并播放所有帧
/// </summary>
[RequireComponent(typeof(Image))]
public class SimpleSpriteAnimation : MonoBehaviour
{
[Header("图集(直接拖入)")]
[Tooltip("拖入 SpriteAtlas 图集,自动提取所有 Sprite")]
public SpriteAtlas atlas;

[Header("播放设置")]
[Tooltip("帧率(每秒播放帧数)")]
public float frameRate = 30f;

[Tooltip("是否自动播放")]
public bool playOnStart = true;

[Tooltip("是否循环播放")]
public bool loop = true;

// 提取的精灵帧
private Sprite[] frames;

// 当前帧索引
private int currentFrame = 0;

// 计时器
private float timer = 0f;

// 播放状态
private bool isPlaying = false;

// Image组件
private Image image;

/// <summary>
/// 总帧数
/// </summary>
public int FrameCount => frames?.Length ?? 0;

/// <summary>
/// 是否正在播放
/// </summary>
public bool IsPlaying => isPlaying;

private void Awake()
{
image = GetComponent<Image>();
}

private void Start()
{
ExtractFramesFromAtlas();

if (playOnStart && frames != null && frames.Length > 0)
{
Play();
}
}

private void Update()
{
if (!isPlaying || frames == null || frames.Length == 0)
return;

timer += Time.deltaTime;
float interval = 1f / frameRate;

while (timer >= interval)
{
timer -= interval;
NextFrame();
}
}

/// <summary>
/// 从 SpriteAtlas 提取所有帧
/// </summary>
private void ExtractFramesFromAtlas()
{
if (atlas == null)
return;

// 获取图集中的 Sprite 数量
int spriteCount = atlas.spriteCount;
frames = new Sprite[spriteCount];

// 提取所有 Sprite
Sprite[] tempSprites = new Sprite[spriteCount];
atlas.GetSprites(tempSprites);

// 按名称数字排序
System.Array.Sort(tempSprites, (a, b) =>
{
int numA = ExtractNumber(a.name);
int numB = ExtractNumber(b.name);
return numA.CompareTo(numB);
});

frames = tempSprites;
}

/// <summary>
/// 从 Sprite 名称中提取数字用于排序
/// </summary>
private int ExtractNumber(string name)
{
// 移除 "(Clone)" 后缀(GetSprites 会添加)
name = name.Replace("(Clone)", "");

int number;
if (int.TryParse(name, out number))
return number;

// 尝试提取数字部分
for (int i = 0; i < name.Length; i++)
{
if (char.IsDigit(name[i]))
{
int start = i;
while (i < name.Length && char.IsDigit(name[i]))
i++;
if (int.TryParse(name.Substring(start, i - start), out number))
return number;
}
}

return int.MaxValue;
}

/// <summary>
/// 播放动画
/// </summary>
public void Play()
{
if (frames == null || frames.Length == 0)
{
ExtractFramesFromAtlas();
}

if (frames == null || frames.Length == 0)
return;

isPlaying = true;
timer = 0f;
UpdateFrame();
}

/// <summary>
/// 暂停动画
/// </summary>
public void Pause()
{
isPlaying = false;
}

/// <summary>
/// 停止动画(暂停并重置到第一帧)
/// </summary>
public void Stop()
{
isPlaying = false;
currentFrame = 0;
timer = 0f;
UpdateFrame();
}

/// <summary>
/// 重新播放
/// </summary>
public void Replay()
{
currentFrame = 0;
timer = 0f;
Play();
}

/// <summary>
/// 跳转到下一帧
/// </summary>
private void NextFrame()
{
currentFrame++;

if (currentFrame >= frames.Length)
{
if (loop)
{
currentFrame = 0;
}
else
{
currentFrame = frames.Length - 1;
isPlaying = false;
return;
}
}

UpdateFrame();
}

/// <summary>
/// 更新显示的帧
/// </summary>
private void UpdateFrame()
{
if (frames != null && frames.Length > 0 && image != null)
{
image.sprite = frames[currentFrame];
}
}
}

Resource下文件

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/12 23:54:24

在Cursor中配置MCP Server

MCP Server 是 Model Context Protocol Server&#xff0c;可以理解为“给 AI 提供外部能力和上下文的服务”。 简单说&#xff0c;它像是 AI 和外部世界之间的“标准化适配器”&#xff1a; AI 本身只会对话和推理MCP Server 把某种能力包装成统一协议这样 AI 就能安全、规范…

作者头像 李华
网站建设 2026/5/12 23:53:35

2026亲测靠谱的商业模式技术公司

在市场竞争持续白热化的2026年&#xff0c;越来越多的企业主发现&#xff0c;单纯依靠流量红利或价格战已难以为继&#xff0c;业绩增长的瓶颈往往源于商业模式本身的陈旧。不少企业投入大量资源进行产品迭代或营销推广&#xff0c;但收效甚微&#xff0c;根源就在于缺少一套系…

作者头像 李华
网站建设 2026/5/12 23:52:56

Visual C++运行库合集AIO:一站式解决Windows程序依赖问题

Visual C运行库合集AIO&#xff1a;一站式解决Windows程序依赖问题 【免费下载链接】vcredist AIO Repack for latest Microsoft Visual C Redistributable Runtimes 项目地址: https://gitcode.com/gh_mirrors/vc/vcredist Visual C运行库合集AIO&#xff08;All-in-On…

作者头像 李华
网站建设 2026/5/12 23:52:07

Python 高级编程 013:抽象基类深度解析

Python 高级编程 013&#xff1a;抽象基类深度解析 Bilibili 同步视频一、&#x1f4a1; 极简起步&#xff1a;用 NotImplementedError 模拟抽象约束1.1 核心思路1.2 代码示例&#xff08;以缓存基类为例&#xff09;1.3 优缺点速览 二、⚙️ 标准方案&#xff1a;用 abc 模块实…

作者头像 李华
网站建设 2026/5/12 23:52:07

【Java EE】Cookie

Cookie为什么需要 Cookie认证流程详解Session 对象SessionIdCookie 传递过期机制安全相关配置注销处理分布式环境注意事项为什么需要 Cookie HTTP 是无状态协议&#xff0c;每次请求相互独立&#xff0c;服务器默认无法判断两次请求是否来自同一用户。同时&#xff0c;浏览器出…

作者头像 李华