Unity3d 序列帧播放

using UnityEngine;
using UnityEngine.UI;
using System.Collections;
using System.IO;

public class SequenceFrameAnimation : MonoBehaviour
{

    public static SequenceFrameAnimation instance;

    #region Attributes

    [SerializeField]
    RawImage mUnitySprite;
    [Header("当前帧图片"), SerializeField]
    Texture texture;
    [Header("序列帧路径,Resources 文件加下")]
    public string m_Path;
    [Header("最大循环帧数"), Range(0, 500)]
    public int framesMax;
    [Header("当前帧数")]
    public int frameIndex = 0;
    [Header("帧率"), SerializeField]
    protected float framerate = 20;
    [Header("忽略时间缩放,影响序列帧播放速度")]
    bool ignoreTimeScale = true;
    [Header("是否循环")]
    public bool loop = true;
    [Header("是否播放")]
    public bool isPlay = true;
    float mUpdate = 0f;
    CanvasGroup canvasGroup;
    /// <summary>
    /// Returns is the animation is still playing or not
    /// </summary>

    public bool isPlaying { get { return enabled; } }
    /// <summary>
    /// Animation framerate.
    /// </summary>
    public float framesPerSecond { get { return framerate; } set { framerate = value; } }

    /// <summary>
    /// Real time since startup.
    /// </summary>
    static public float realtime { get { return Time.unscaledTime; } }

    #endregion

    #region Unity3d Function

    private void Awake()
    {
        if (!instance)
        {
            instance = this;
        }
    }

    void Start()
    {
        if (mUnitySprite)
        {
            canvasGroup = mUnitySprite.gameObject.AddComponent<CanvasGroup>();
            canvasGroup.alpha = 0;
        }
    }
    void Update()
    {
        UpdateRun();
    }

    #endregion

    #region Public Function

    /// <summary>
    /// 设置序列帧路径
    /// </summary>
    /// <param name="path"></param>
    public void SetFilePath(string path)
    {
        if (!string.IsNullOrEmpty(path))
        {
            m_Path = path;
            string filePath = Application.dataPath + "/Resources/" + m_Path;
            filePath = filePath.Replace("//","\\");
            string[] files = Directory.GetFiles(@filePath, "*.png");
            framesMax= files.Length;
        }
    }
    /// <summary>
    /// 播放
    /// </summary>
    public void Play()
    {
        if (framesMax > 0)
        {
            if (!enabled && !loop)
            {
                int newIndex = framerate > 0 ? frameIndex + 1 : frameIndex - 1;

                if (newIndex < 0 || newIndex >= framesMax)
                {
                    frameIndex = framerate < 0 ? framesMax - 1 : 0;
                }
            }

            enabled = isPlay = true;

            UpdateSprite();
        }
    }
    /// <summary>
    /// 播放指定文件路径
    /// </summary>
    /// <param name="filepath"></param>
    public void Play(string filepath)
    {
        if (string.IsNullOrEmpty(filepath) || framesMax <= 0)
            return;

        m_Path = filepath;

        if (framesMax > 0)
        {
            if (!enabled && !loop)
            {
                int newIndex = framerate > 0 ? frameIndex + 1 : frameIndex - 1;

                if (newIndex < 0 || newIndex >= framesMax)
                {
                    frameIndex = framerate < 0 ? framesMax - 1 : 0;
                }
            }

            enabled = isPlay = true;

            UpdateSprite();
        }
    }
    /// <summary>
    /// 暂停播放
    /// </summary>
    public void Pause()
    {
        enabled = isPlay = false;
        Resources.UnloadUnusedAssets();
    }
    /// <summary>
    /// 停止播放并关闭
    /// </summary>
    public void Stop()
    {
        if (canvasGroup)
        {
            canvasGroup.alpha = 0.0f;
        }
        enabled = isPlay = false;
        texture = null;
        frameIndex = 0;
        m_Path = "";
        Resources.UnloadUnusedAssets();
        System.GC.Collect();
    }
    /// <summary>
    /// 从第一帧重新播放
    /// </summary>
    public void ResetToBeginning()
    {
        Resources.UnloadAsset(texture);
        frameIndex = framerate < 0 ? framesMax - 1 : 0;
        isPlay = enabled = true;
        UpdateSprite();
    }


    #endregion

    #region 核心逻辑代码

    /// <summary>
    /// Update使用
    /// </summary>
    void UpdateRun()
    {
        if (framesMax == 0)
        {
            enabled = isPlay = false;
        }
        else if (framerate != 0)
        {
            if (isPlay)
            {
                float time = ignoreTimeScale ? realtime : Time.time;

                if (mUpdate < time)
                {
                    mUpdate = time;

                    int newIndex = framerate > 0 ? frameIndex + 1 : frameIndex - 1;

                    if (!loop && (newIndex < 0 || newIndex >= framesMax))
                    {
                        enabled = isPlay = false;
                        return;
                    }

                    frameIndex = RepeatIndex(newIndex, framesMax);

                    UpdateSprite();
                }
            }
        }
    }

    /// <summary>
    ///立即更新可见的精灵。
    /// </summary>
    void UpdateSprite()
    {
        if (mUnitySprite == null)
        {
            if (mUnitySprite == null)
            {
                enabled = false;
                return;
            }
        }

        if (isPlay)
        {

            if (canvasGroup && canvasGroup.alpha != 1.0f)
            {
                canvasGroup.alpha = 1.0f;
            }


            float time = ignoreTimeScale ? realtime : Time.time;

            if (framerate != 0)
            {
                mUpdate = time + Mathf.Abs(1f / framerate);
            }

            if (mUnitySprite != null)
            {
                Resources.UnloadAsset(texture);
                texture = (Texture)(Resources.Load(m_Path + "/" + frameIndex.ToString()) as Texture2D);
                mUnitySprite.texture = texture;

            }
        }
    }

    /// <summary>
    /// 使用重复逻辑包装索引,以便例如+1过去,表示索引为'1'。
    /// </summary>
    [System.Diagnostics.DebuggerHidden]
    [System.Diagnostics.DebuggerStepThrough]
    private int RepeatIndex(int val, int max)
    {
        if (max < 1) return 0;
        while (val < 0) val += max;
        while (val >= max) val -= max;
        return val;
    }

    #endregion
}


  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值