Unity UI實(shí)現(xiàn)循環(huán)播放序列圖
一、思路
1.獲取播放組件
一般我們使用UI的Raw Image或者Image來(lái)顯示圖片
Image:僅支持Sprite類(lèi)型圖片,需要更改圖片的格式(注意:在StreamingAssets文件夾里的圖片是更改不了類(lèi)型的,在這里必須放在Assets/Resources路徑下)

Raw Image:支持圖片的原格式,一般我們將其轉(zhuǎn)換成 Texture2D使用
2.加載圖片
Resources提供了一個(gè)Load方法,可以從Resources文件夾里加載圖片。
?。。。?!注意一定要在Resources路徑下,否則找不到
Resources.Load(path, typeof(Texture2D)) as Texture2D; Resources.Load(path, typeof(Sprite)) as Sprite;
3.循環(huán)加載
記錄當(dāng)前到哪一張,判斷是不是到了最后一張,是,加載第一張
二、示例代碼
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("基礎(chǔ)名稱(chēng)(基礎(chǔ)名字就是序列圖名稱(chēng)中絕對(duì)相同的)")]
public string BaseName;
[Header("有效數(shù)字的位數(shù)(代表排序的有效數(shù)字位數(shù))")]
public int SignificantDigits;
[Header("開(kāi)始數(shù)(開(kāi)始的數(shù))")]
public int Start;
[Header("總數(shù)(一共多少?gòu)垐D片)")]
public int Count;
public NameRules(string _name,int _digits,int _start,int _count)
{
BaseName = _name;
SignificantDigits = _digits;
Start = _start;
Count = _count;
}
}
//圖片類(lèi)型
public enum WidgetType
{
Image,
RawImage
}
///
[Header("圖片顯示控件(RawImage[支持原始圖片類(lèi)型] OR Image[僅支持Sprite圖片])")]
public WidgetType ImgWidget = WidgetType.RawImage;
//要求文件夾必須在Assets/Resources文件夾里面,ModeName填寫(xiě)后面到文件夾的路徑
[Header("模式名稱(chēng)(和文件夾名稱(chēng)相同,路徑必須在Resources里面)")]
public string ModeName = "請(qǐng)?zhí)顚?xiě)文件夾路徑";
[Header("命名規(guī)則(序列圖的命名規(guī)則)")]
public NameRules Rules;
[Header("FPS(一秒內(nèi)顯示多少?gòu)垐D片)")]
public int FramesPerSecond = 24;
[Header("循環(huán)播放(默認(rèn)開(kāi)啟)")]
public bool Loop=true;
[Header("UI可用時(shí)自動(dòng)播放(默認(rèn)開(kāi)啟)")]
public bool PlayOnWake=true;
/// <summary>
/// 私有變量
/// </summary>
/// /// 顯示圖片的UI控件
private Image ImageComponent = null;
private RawImage RawImgComponent = null;
private int currentFrames;//當(dāng)前播放的圖片幀數(shù)
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();
}
}
//開(kāi)始播放
public void Play(bool needLoop=true)
{
Playing = true;
Loop = needLoop;
}
//停止播放
public void Stop()
{
Playing = false;
}
private Sprite GetCurrentSprite()
{
/這個(gè)是重點(diǎn),顯示不出來(lái)圖片的話(huà),大概率問(wèn)題在這個(gè)函數(shù)
string formatStr = "{0:D" + Rules.SignificantDigits + "}";//保留有效數(shù)字,不夠前面加0
string imageName = ModeName + "/" + Rules.BaseName + string.Format(formatStr, currentFrames);
return LoadSprite(imageName);
}
private Texture2D GetCurrentTexture2D()
{
/這個(gè)是重點(diǎn),顯示不出來(lái)圖片的話(huà),大概率問(wèn)題在這個(gè)函數(shù)
string formatStr = "{0:D"+ Rules .SignificantDigits+ "}";//保留有效數(shù)字,不夠前面加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("此組件上沒(méi)有找到<Image>!請(qǐng)檢查后重試!");
EditorStop();
}
}
else
{
RawImgComponent = transform.gameObject.GetComponent<RawImage>();
if (RawImgComponent == null)
{
EditorBox("此組件上沒(méi)有找到<RawImage>!請(qǐng)檢查后重試!");
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, "確認(rèn)", "取消");
#endif
}
/// <summary>
/// Unity編輯器停止當(dāng)前正在運(yùn)行的程序
/// </summary>
private void EditorStop()
{
#if UNITY_EDITOR
UnityEditor.EditorApplication.isPlaying = false;
#endif
}
}



以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
解決C#中WebBrowser的DocumentCompleted事件不執(zhí)行的實(shí)現(xiàn)方法
本篇文章是對(duì)C#中WebBrowser的DocumentCompleted事件不執(zhí)行解決方法進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下2013-05-05
C#中使用Join與GroupJoin將兩個(gè)集合進(jìn)行關(guān)聯(lián)與分組
這篇文章主要介紹了C#中使用Join與GroupJoin將兩個(gè)集合進(jìn)行關(guān)聯(lián)與分組,文中分別對(duì)Join和GroupJoin的用法進(jìn)行詳細(xì)說(shuō)明,需要的朋友可以參考下2017-12-12
.net實(shí)現(xiàn)文件讀寫(xiě)的幾種常用方法
這篇文章主要介紹了.net實(shí)現(xiàn)文件讀寫(xiě)的幾種常用方法,非常實(shí)用,需要的朋友可以參考下2014-08-08
Winform窗體縮放下使用剪切板功能出現(xiàn)頁(yè)面閃動(dòng)解決分析
這篇文章主要介紹了Winform窗體縮放下使用剪切板功能出現(xiàn)頁(yè)面閃動(dòng)解決分析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-11-11
C#實(shí)現(xiàn)給DataGrid單元行添加雙擊事件的方法
這篇文章主要介紹了C#實(shí)現(xiàn)給DataGrid單元行添加雙擊事件的方法,較為詳細(xì)的分析了C#給DataGrid單元添加雙擊事件的步驟及相關(guān)實(shí)現(xiàn)代碼,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2015-07-07
C#實(shí)現(xiàn)DataTable轉(zhuǎn)換成IList的方法
這篇文章主要介紹了C#實(shí)現(xiàn)DataTable轉(zhuǎn)換成IList的方法,涉及C#針對(duì)DataTable操作的相關(guān)技巧,需要的朋友可以參考下2016-03-03

