Unity UI 循环序列图的实现
最编程
2024-04-22 22:49:08
...
一、思路
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 } }
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
上一篇: 南京邮电大学[物理实验室(上)]
下一篇: 为什么金融系统只保留小数点后两位数?
推荐阅读
-
Java 8新特性探究(十三)JavaFX 8新特性以及开发2048游戏-JavaFX历史## 跟java在服务器端和web端成绩相比,桌面一直是java的软肋,于是Sun公司在2008年推出JavaFX,弥补桌面软件的缺陷,请看下图JavaFX一路走过来的改进 从上图看出,一开始推出时候,开发者需使用一种名为JavaFX Script的静态的、声明式的编程语言来开发JavaFX应用程序。因为JavaFX Script将会被编译为Java bytecode,程序员可以使用Java代码代替。 JavaFX 2.0之后的版本摒弃了JavaFX Script语言,而作为一个Java API来使用。因此使用JavaFX平台实现的应用程序将直接通过标准Java代码来实现。 JavaFX 2.0 包含非常丰富的 UI 控件、图形和多媒体特性用于简化可视化应用的开发,WebView可直接在应用中嵌入网页;另外 2.0 版本允许使用 FXML 进行 UI 定义,这是一个脚本化基于 XML 的标识语言。 从JDK 7u6开始,JavaFx就与JDK捆绑在一起了,JavaFX团队称,下一个版本将是8.0,目前所有的工作都已经围绕8.0库进行。这是因为JavaFX将捆绑在Java 8中,因此该团队决定跳过几个版本号,迎头赶上Java 8。 ##JavaFx8的新特性 ## ###全新现代主题:Modena 新的Modena主题来替换原来的Caspian主题。不过在Application的start方法中,可以通过setUserAgentStylesheet(STYLESHEET_CASPIAN)来继续使用Caspian主题。 参考http://fxexperience.com/2013/03/modena-theme-update/ ###JavaFX 3D 在JavaFX8中提供了3D图像处理API,包括Shape3D (Box, Cylinder, MeshView, Sphere子类),SubScene, Material, PickResult, LightBase (AmbientLight 和PointLight子类),SceneAntialiasing等。Camera类也得到了更新。从JavaDoc中可以找到更多信息。 ###富文本 强化了富文本的支持 ###TreeTableView ###日期控件DatePicker 增加日期控件 ###用于 CSS 结构的公共 API
-
如何实现Swagger-UI与Spring Cloud的整合与安全设置
-
走台阶问题的算法:通过递归实现(2种递归方法+递归改循环)
-
探究C语言中循环的实现方式
-
C语言中循环的实现方式
-
重写的标题:在C语言中实现数字和字符串的循环位移操作
-
用循环方法实现C语言的排列组合
-
使用C语言实现环形缓冲区(循环缓冲区)-- Circular Buffer (Ring Buffer)的创建
-
如何用G74指令实现端面切槽的啄钻循环加工?
-
在VUE element-ui中实现表格的横向展示与表尾汇总功能