Unity UI实现循环播放序列图
作者:PangCoder 发布时间:2023-03-14 15:51:10
标签:Unity,UI,循环播放
一、思路
1.获取播放组件
一般我们使用UI的Raw Image或者Image来显示图片
Image:仅支持Sprite类型图片,需要更改图片的格式(注意:在StreamingAssets文件夹里的图片是更改不了类型的,在这里必须放在Assets/Resources路径下)
Raw Image:支持图片的原格式,一般我们将其转换成 Texture2D使用
2.加载图片
Resources提供了一个Load方法,可以从Resources文件夹里加载图片。
!!!!!注意一定要在Resources路径下,否则找不到
Resources.Load(path, typeof(Texture2D)) as Texture2D;
Resources.Load(path, typeof(Sprite)) as Sprite;
3.循环加载
记录当前到哪一张,判断是不是到了最后一张,是,加载第一张
二、示例代码
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using UnityEditor;
using UnityEngine;
using UnityEngine.UI;
public class FramesController : MonoBehaviour
{
[System.Serializable]
public struct NameRules
{
[Header("基础名称(基础名字就是序列图名称中绝对相同的)")]
public string BaseName;
[Header("有效数字的位数(代表排序的有效数字位数)")]
public int SignificantDigits;
[Header("开始数(开始的数)")]
public int Start;
[Header("总数(一共多少张图片)")]
public int Count;
public NameRules(string _name,int _digits,int _start,int _count)
{
BaseName = _name;
SignificantDigits = _digits;
Start = _start;
Count = _count;
}
}
//图片类型
public enum WidgetType
{
Image,
RawImage
}
///
[Header("图片显示控件(RawImage[支持原始图片类型] OR Image[仅支持Sprite图片])")]
public WidgetType ImgWidget = WidgetType.RawImage;
//要求文件夹必须在Assets/Resources文件夹里面,ModeName填写后面到文件夹的路径
[Header("模式名称(和文件夹名称相同,路径必须在Resources里面)")]
public string ModeName = "请填写文件夹路径";
[Header("命名规则(序列图的命名规则)")]
public NameRules Rules;
[Header("FPS(一秒内显示多少张图片)")]
public int FramesPerSecond = 24;
[Header("循环播放(默认开启)")]
public bool Loop=true;
[Header("UI可用时自动播放(默认开启)")]
public bool PlayOnWake=true;
/// <summary>
/// 私有变量
/// </summary>
/// /// 显示图片的UI控件
private Image ImageComponent = null;
private RawImage RawImgComponent = null;
private int currentFrames;//当前播放的图片帧数
private float showTime = 0.0f;
private float rateTime = 0.0f;
private bool Playing;
// Start is called before the first frame update
void Start()
{
InitWidget();
}
// Update is called once per frame
void Update()
{
if (!Playing) return;
showTime += Time.deltaTime;
if (showTime >= rateTime)
{
showTime = 0;
currentFrames++;
if (currentFrames >= Rules.Count)
{
if(Loop)
{
currentFrames = Rules.Start;
}else
{
Playing = false;
}
}
if(ImgWidget == WidgetType.Image)
{
ImageComponent.sprite = GetCurrentSprite();
}
else
{
RawImgComponent.texture = GetCurrentTexture2D();
}
}
}
/// /更换播放的序列图
public void ChangeMode(string _mode, NameRules _rules, int _fps=24)
{
ModeName = _mode;
Rules=_rules;
FramesPerSecond = _fps;
currentFrames = Rules.Start;
rateTime = 1.0f / FramesPerSecond;
if (ImgWidget == WidgetType.Image)
{
ImageComponent.sprite = GetCurrentSprite();
}
else
{
RawImgComponent.texture = GetCurrentTexture2D();
}
}
//开始播放
public void Play(bool needLoop=true)
{
Playing = true;
Loop = needLoop;
}
//停止播放
public void Stop()
{
Playing = false;
}
private Sprite GetCurrentSprite()
{
/这个是重点,显示不出来图片的话,大概率问题在这个函数
string formatStr = "{0:D" + Rules.SignificantDigits + "}";//保留有效数字,不够前面加0
string imageName = ModeName + "/" + Rules.BaseName + string.Format(formatStr, currentFrames);
return LoadSprite(imageName);
}
private Texture2D GetCurrentTexture2D()
{
/这个是重点,显示不出来图片的话,大概率问题在这个函数
string formatStr = "{0:D"+ Rules .SignificantDigits+ "}";//保留有效数字,不够前面加0
string imageName = ModeName+"/"+Rules.BaseName + string.Format(formatStr, currentFrames);
return LoadTexture2D(imageName);
}
private Texture2D LoadTexture2D(string path)
{
return Resources.Load(path, typeof(Texture2D)) as Texture2D;
}
private Sprite LoadSprite(string path)
{
return Resources.Load(path, typeof(Sprite)) as Sprite;
}
/// <summary>
/// 初始化图片显示组件
/// </summary>
private void InitWidget()
{
if(ImgWidget== WidgetType.Image)
{
ImageComponent = transform.gameObject.GetComponent<Image>();
if(ImageComponent==null)
{
EditorBox("此组件上没有找到<Image>!请检查后重试!");
EditorStop();
}
}
else
{
RawImgComponent = transform.gameObject.GetComponent<RawImage>();
if (RawImgComponent == null)
{
EditorBox("此组件上没有找到<RawImage>!请检查后重试!");
EditorStop();
}
}
Playing = PlayOnWake;
currentFrames = Rules.Start;
rateTime = 1.0f / FramesPerSecond;
if (ImgWidget == WidgetType.Image)
{
ImageComponent.sprite = GetCurrentSprite();
}
else
{
RawImgComponent.texture = GetCurrentTexture2D();
}
}
/// <summary>
/// Unity编辑器的MessageBox
/// </summary>
private void EditorBox(string msg)
{
#if UNITY_EDITOR
EditorUtility.DisplayDialog("FramesController", msg, "确认", "取消");
#endif
}
/// <summary>
/// Unity编辑器停止当前正在运行的程序
/// </summary>
private void EditorStop()
{
#if UNITY_EDITOR
UnityEditor.EditorApplication.isPlaying = false;
#endif
}
}
来源:https://blog.csdn.net/qq_36251561/article/details/119426503
0
投稿
猜你喜欢
- 求数组中最大的数的值:1、数组的max函数:class Program { &nb
- 本文实例为大家分享了java实现选课系统的具体代码,供大家参考,具体内容如下这个程序主要是练习IO(文件读写,序列化),集合框架的使用学生端
- println()直接打印我们都知道println()如果打印的是基本数据类型的话直接打印出来的就是值,你如果是引用数据类型呢?🍑除掉这四类
- 前言今天收到一封邮件,大概内容如下:spring boot鼓励去配置化,那么怎么将第三方jar包中的xml去配置化了?其实,这个问题,在前面
- 前言随着使用 Spring 进行开发的个人和企业越来越多,Spring 也慢慢从一个单一简洁的小框架变成一个大而全的开源软件,Spring
- 前言:小伙伴说能不能用springboot整合一下mybatis多数据源不使用JPA进行数据库连接操作。那么说干就干创建一个springbo
- AppWidgetProvider 用来在HOME页面显示插件实现步骤:1、为AppWidget提供一个元布局文件AppWigdetProv
- Java停止线程的逻辑(协同、通知)在Java程序中,我们想要停止一个线程可以通过interrupt方法进行停止。但是当我们调用interr
- Android超清晰6.0权限申请AndPermission的具体实现代码,供大家参考,具体内容如下前言这是我经常使用的框架,原因:1.思路
- 前言此文适合了解了es相关概念以及基础知识的同学阅读elasticsearch简介Elasticsearch是一个基于Lucene的搜索服务
- 时钟的使用1、声明VOID CALLBACK playproc( HWND hwnd, &nb
- 近几天又温习了一下SpringMVC的运行机制以及原理我理解的springmvc,是设计模式MVC中C层,也就是Controller(控制)
- 简介机器学习在全球范围内越来越受欢迎和使用。 它已经彻底改变了某些应用程序的构建方式,并且可能会继续成为我们日常生活中一个巨大的(并且正在增
- 当前单元格指的是DataGridView焦点所在的单元格,它可以通过DataGridView对象的CurrentCell属性取得。如果当前单
- 引言第一眼看到这个题目,我相信大家都会脑子里面弹出来一个想法:这不都是 Spring 的注解么,加了这两个注解的类都会被最终封装成 Bean
- 一、Mybatis中的延迟加载1、延迟加载背景:Mybatis中Mapper配置文件中的resultMap可以实现高级映射(使用associ
- AspectJ简介它不属于spring;AspectJ是一个AOP的框架;定义了AOP语法;有一个专门的编译器用来生成遵守Java字节编码规
- C#中Invoke的用法()invoke和begininvoke 区别一直对invoke和begininvoke的使用和概念比较混乱,这两天
- Activity中Toast的使用Toast.makeText(this,"ADD",Toast.LENGTH_SHOR
- 01-前言:什么是循环依赖?首先,我们先明确下依赖的定义。 如果一个 Bean bar 的属性,引用了容器中的另外一个 Bean foo,那