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
    }
}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • Unity代码实现序列帧动画播放器

    序列帧动画经常用到,最直接的方式就是用Animation录制.但某些情况下这种方式并不是太友好,需要靠代码的方式进行序列帧动画的实现. 代码实现序列帧动画,基本的思路是定义一个序列帧的数组/列表,根据时间的流逝来确定使用哪一帧并更新显示. NGUI的UI2DSpriteAnimation已经实现了此功能,但是它支持的目标只有Native2D的SpriteRenderer组件或者NGUI自身的UI2DSprite组件,并不支持UGUI的Image组件. 当然可以通过改写源码的方式来添加对Image

  • Unity实现音频播放管理器

    本文实例为大家分享了Unity实现音频播放管理器的具体代码,供大家参考,具体内容如下 1.模块化,直接用.创建一个空物体,把此脚本拖上去,然后把需要播放的所有音频拖到面板上的"AudioList"中: 2.通过AudioManagerP._instance直接调用方法,包含: 暂停: 继续播放: 停止播放: 播放背景音乐(0号播放器专用于播放背景音): 直接播放声音(带参数1.播放器序号  2.音频的名字    3.声音大小    4.   是否循环): 直接播放呻吟(带参数1.播放器

  • Unity UI实现循环播放序列图

    一.思路 1.获取播放组件 一般我们使用UI的Raw Image或者Image来显示图片 Image:仅支持Sprite类型图片,需要更改图片的格式(注意:在StreamingAssets文件夹里的图片是更改不了类型的,在这里必须放在Assets/Resources路径下) Raw Image:支持图片的原格式,一般我们将其转换成 Texture2D使用 2.加载图片 Resources提供了一个Load方法,可以从Resources文件夹里加载图片. !!!!!注意一定要在Resources路

  • iOS实现自动循环播放的banner实例详解

    前言 对于banner轮播图,相信大家都会经常用到.自动循环播放的banner是很常见的UI组件.如何实现呢?下面就来给大家详细介绍下,话不多说了,下面来一起学习学习吧. 1.实现思路 1.横向滚动的banner. UIScrollViw+UIImageView. UICollectionView+UICollectionViewCell. 前者需要自己做重用UIImageView,后者可以直接重用UICollectionViewCell.如果前者没有做重用,多占用内存. 2.自动循环播放ban

  • Unity实现卡片循环滚动效果的示例详解

    目录 简介 定义卡片的摆放规则 调整卡片的层级关系 调整卡片的尺寸大小 动态调整位置.层级和大小 移动动画 按钮事件 简介 功能需求如图所示,点击下一个按钮,所有卡片向右滚动,其中最后一张需要变更为最前面的一张,点击上一个按钮,所有卡片向左滚动,最前面的一张需要变更为最后一张,实现循环滚动效果. 最中间的一张表示当前选中项,变更为选中项的滚动过程中,需要逐渐放大到指定值,相反则需要恢复到默认大小. 实现思路: 定义卡片的摆放规则: 调整卡片的层级关系: 调整卡片的尺寸大小: 卡片向指定方向移动,

  • iOS 用Swipe手势和动画实现循环播放图片示例

    主要想法 添加3个ImageView展示图片,实现图片的无限循环. 使用Swipe手势识别用户向右或向左滑动图片. 使用CATransition给ImageView.layer添加动画,展示图片更换的效果. 实现 在storyboard添加三个UIImageView,用来展示图片.而数组imageArray则用来保存图片对象. @interface ViewController () @property (strong, nonatomic) IBOutlet UIImageView *midd

  • Android实战打飞机游戏之无限循环的背景图(2)

    首先分析下游戏界面内的元素: 无限滚动的背景图, 可以操作的主角,主角的子弹, 主角的血量,两种怪物(敌机),一个boss, boss的爆炸效果. 先看效果图 1.首先实现无限滚动的背景图 原理: 定义两个位图对象 当第一个位图到末尾是 第二个位图从第一个位图的末尾跟上. public class GameBg { // 游戏背景的图片资源 // 为了循环播放,这里定义两个位图对象, // 其资源引用的是同一张图片 private Bitmap bmpBackGround1; private B

  • iOS使用UIScrollView实现无限循环轮播图效果

    本文实例为大家分享了iOS使用UIScrollView实现无限循环轮播图的具体代码,供大家参考,具体内容如下 代码: // // ViewController.m // 无限轮播 // // Created by limin on 17/8/23. // Copyright © 2017年 none. All rights reserved. // #import "ViewController.h" @interface ViewController ()<UIScrollVi

  • Unity3D实现播放gif图功能

    Unity是不识别Gif格式图的,需要我们使用c#将gif里多帧图转化为Texture2D格式.需要使用System.Drawing.dll.此dll在unity安装目录下就可以找到.由于unity没有gif格式的文件,所以我们无法在面板指定,需要动态加载.所以将gif图放在StreamingAssets文件夹下.以下为源代码: using System; using System.Collections; using System.Collections.Generic; using Syst

  • viewpager实现自动循环轮播图

    本文实例为大家分享了viewpager自动循环轮播图的具体代码,供大家参考,具体内容如下 布局文件 android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MainActivity"> <RelativeLayout android:layout_width="match_parent" and

  • 无限循环轮播图之运动框架(原生JS实现)

    封装运动框架 function getStyle(obj,name){ if(obj.currentStyle){ return obj.currentStyle[name]; }else{ return getComputedStyle(obj,false)[name]; } } function move(obj,json,options){ var options=options || {}; var duration=options.duration || 800; var easing

  • Android ViewPager循环播放广告实例详解

    Android  实现ViewPager循环播放广告条实例详解 我们经常会看到有一些app的banner界面可以实现循环播放多个广告图片和手动滑动循环的效果.看到那样的效果,相信大家都会想到ViewPager,但是ViewPager并不支持循环翻页,所以要实现循环还得需要自己去动手.最后还有一个问题就是翻页到最后一页如何平滑过渡到首页的问题.这些都源于有人私信问我ViewPager广告条如何平滑过渡的问题,出于这个问题,我想着亲自实现并分享下吧,本篇就是为了解决这些问题而写的. 1.初始化布局

随机推荐