Unity學習 — 打包和讀取AB資源,並播放打包的AB序列圖!


本文提供詳細教程

記錄遇到的難點並幫助同行的朋友們

堅持以最簡單的方法傳授和把更好的閱讀體驗帶給你們!


一:效果圖

在這裏插入圖片描述



二:插件下載

網盤資源一鍵下載 (點點關注,不迷路!謝謝支持!!)

提取碼:41i6



三:插件導入!

One
在這裏插入圖片描述
Two
在這裏插入圖片描述
Three
在這裏插入圖片描述
Four
在這裏插入圖片描述
Five
在這裏插入圖片描述
Six
在這裏插入圖片描述
Seven
在這裏插入圖片描述
Eight
在這裏插入圖片描述
Nine
在這裏插入圖片描述



三:代碼!

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class FrameControll : MonoBehaviour
{

    public GameObject Xulie; //序列圖
    public FrameTexturesController XulieFrame; //控制圖片腳本
    public Texture2D[] XulieTu; //讀取到的圖片
    private AssetBundle AB1;
    private readonly string ABPath = Application.streamingAssetsPath + "/wwjj";

    private void Awake()
    {
        AB1 = AssetBundle.LoadFromFile(ABPath);
        XulieTu = AB1.LoadAllAssets<Texture2D>();
        XulieFrame.Frames = XulieTu;
    }

    void Update()
    {
        if (Input.GetMouseButtonDown(0))
        {
            XulieFrame.Play(0, -1, true);
        }
    }
}

控制序列幀播放腳本

using UnityEngine;
using UnityEngine.UI;

public class FrameTexturesController: MonoBehaviour
{
    /// <summary>
    /// 播放狀態
    /// </summary>
    private enum PlayStatus
    {
        /// <summary>
        /// 重置狀態 (重置後會立即返回到原狀態)
        /// </summary>
        reset,
        /// <summary>
        /// 播放開始狀態
        /// </summary>
        play,
        /// <summary>
        /// 回放開始狀態
        /// </summary>
        playback,
        /// <summary>
        /// 暫停開始狀態
        /// </summary>
        pause,
        /// <summary>
        /// 停止開始狀態
        /// </summary>
        stop,
        
        /// <summary>
        /// 播放中狀態
        /// </summary>
        playing,
        /// <summary>
        /// 暫停狀態
        /// </summary>
        paused,
        /// <summary>
        /// 停止狀態
        /// </summary>
        stopped
    }
    
    /// <summary>
    /// 顯示控件
    /// </summary>
    [SerializeField]
    private RawImage rimg_output;
    /// <summary>
    /// 幀速度
    /// </summary>
    [SerializeField]
    private int frameRate;
    
    /// <summary>
    /// 幀序列
    /// </summary>
    public Texture2D[] _frames;
    public Texture2D[] _frames1;

    public Texture2D[] Frames
    {
        set
        {
            _frames = value;
            _timePreFrame = 1f / frameRate;
        }
    }
    public Texture2D[] Frames1
    {
        set
        {
            _frames1 = value;
            _timePreFrame = 1f / frameRate;
        }
    }


    /// <summary>
    /// 播放速度
    /// </summary>
    private float _speed = 1;
    public float Speed
    {
        get => _speed;
        set => _speed = value;
    }

    /// <summary>
    /// 是否循環播放
    /// </summary>
    private bool _isLoop = false;
    public bool IsLoop
    {
        get => _isLoop;
    }

    /// <summary>
    /// 是否正在播放
    /// </summary>
    public bool IsPlaying
    {
        get => _playStatus == PlayStatus.play || _playStatus == PlayStatus.playing;
    }
    
    /// <summary>
    /// 是否正在回放
    /// </summary>
    public bool IsPlaybacking
    {
        get => (_playStatus == PlayStatus.play || _playStatus == PlayStatus.playing) && _realSpeed < 0;
    }
    
    /// <summary>
    /// 開始幀的位置
    /// </summary>
    private int _startFrameIndex = -1;

    /// <summary>
    /// 結束幀的位置(最後一幀的後一幀)
    /// </summary>
    private int _endFrameIndex = -1;
    /// <summary>
    /// 當前播放位置
    /// </summary>
    private int _curFrameIndex;
    /// <summary>
    /// 固有幀間隔時間
    /// </summary>
    private float _timePreFrame;
    /// <summary>
    /// 實際幀間隔時間 := 固有幀間隔時間 / 播放速度
    /// 即,計算了播放速度以後的幀間隔時間
    /// </summary>
    private float _realTimePreFrame;
    /// <summary>
    /// 實際播放速度 := 播放速度 * 播放方向
    /// </summary>
    private float _realSpeed;
    /// <summary>
    /// 當前事件間隔
    /// </summary>
    private float _curTime;
    /// <summary>
    /// 循環次數
    /// </summary>
    private int _loopCount = -1;
    /// <summary>
    /// 播放狀態
    /// </summary>
    private PlayStatus _playStatus = PlayStatus.stop;

    /// <summary>
    /// 播放 
    /// </summary>
    public void Play(int startIndex = 0, int endIndex = -1, bool isLoop = false)
    {
        _isLoop = isLoop;
        _startFrameIndex = startIndex;
        _endFrameIndex = endIndex == -1 ? _frames.Length : endIndex;
        _playStatus = PlayStatus.play;
    }

    /// <summary>
    /// 暫停
    /// </summary>
    public void Pause() => _playStatus = PlayStatus.pause;

    /// <summary>
    /// 回放
    /// </summary>
    public void Playback(int startIndex = -1, int endIndex = -1, bool isLoop = false)
    {
        _isLoop = isLoop;
        _startFrameIndex = startIndex == -1 ? _frames.Length - 1 : startIndex;;
        _endFrameIndex = endIndex;
        _playStatus = PlayStatus.playback;
    }

    /// <summary>
    /// 停止
    /// </summary>
    public void Stop() => _playStatus = PlayStatus.stop;
    
    private void Update()
    {
        CheckPlayStatus();
    }

    /// <summary>
    /// 檢查播放狀態
    /// </summary>
    private void CheckPlayStatus()
    {
        switch (_playStatus)
        {
            case PlayStatus.pause:
                OnPause();
                break;
            case PlayStatus.play:
                OnPlay();
                break;
            case PlayStatus.playback:
                OnPlayback();
                break;
            case PlayStatus.reset:
                OnReset();
                break;
            case PlayStatus.stop:
                OnStop();
                break;
            case PlayStatus.playing:
                OnPlaying();
                break;
            case PlayStatus.paused:
                break;
            case PlayStatus.stopped:
                break;
        }
    }

    /// <summary>
    /// 暫停開始狀態處理
    /// </summary>
    private void OnPause()
    {
        
    }

    /// <summary>
    /// 播放開始狀態處理
    /// </summary>
    private void OnPlay()
    {
        if (_speed == 0)    // 播放速度如果爲0,則進入暫停狀態
        {
            _playStatus = PlayStatus.pause;
            return;
        }
        
        _realSpeed = _speed > 0 ? _speed : -_speed;        // 計算實際播放速度
        _realTimePreFrame = _timePreFrame / _realSpeed;    // 計算實際幀間隔時間
        _curTime = 0;                                      // 重置當前計時時間
        _curFrameIndex = _startFrameIndex;                 // 重置回播放起始位置
        rimg_output.texture = _frames[_curFrameIndex];     // 顯示起始畫面
        _curFrameIndex++;                                  // 將位置指針移至下一位
        
        _playStatus = PlayStatus.playing;                  // 進入播放狀態
    }

    /// <summary>
    /// 回放開始狀態處理
    /// </summary>
    private void OnPlayback()
    {
        if (_speed == 0)    // 播放速度如果爲0,則進入暫停狀態
        {
            _playStatus = PlayStatus.pause;
            return;
        }
        
        _realSpeed = _speed < 0 ? _speed : -_speed;        // 計算實際播放速度
        _realTimePreFrame = _timePreFrame / (-_realSpeed); // 計算實際幀間隔時間
        _curTime = 0;                                      // 重置當前計時時間
        _curFrameIndex = _startFrameIndex;                 // 重置回播放起始位置
        rimg_output.texture = _frames[_curFrameIndex];     // 顯示起始畫面
        _curFrameIndex--;                                  // 將位置指針移至下一位
        
        _playStatus = PlayStatus.playing;                  // 進入播放狀態
    }

    /// <summary>
    /// 重置狀態處理
    /// </summary>
    private void OnReset()
    {
        
    }

    /// <summary>
    /// 停止開始狀態處理
    /// </summary>
    private void OnStop()
    {
        //rimg_output.texture = null;
        _playStatus = PlayStatus.stopped;
    }

    /// <summary>
    /// 播放中狀態處理
    /// </summary>
    private void OnPlaying()
    {
        if (_curTime < _realTimePreFrame)    // 當前計時未達到實際幀間隔時間
        {
            _curTime += Time.deltaTime;      // 不做任何操作,僅累加計時時間
        }
        else
        {
            if (_curFrameIndex != _endFrameIndex)                      // 當前幀未到達結束位置
            {
                rimg_output.texture = _frames[_curFrameIndex];       // 顯示當前幀畫面
                _curFrameIndex += _realSpeed > 0 ? 1 : -1;           // 將位置指針移至下一位
                _curTime = 0;
            }
            else
            {
                if (_isLoop)                                           // 啓用循環播放
                {
                    Play(_startFrameIndex, _endFrameIndex, true);    // 重新播放
                }
                else
                {
                    Pause();                                          // 暫停播放
                }
            }
        }
    }
}

在這裏插入圖片描述



四:Demo學習

Demo一鍵下載 (點點關注,不迷路!謝謝支持!!)

提取碼:9msb




五:關於AB資源打包的學習和拓展

在後期的項目中,用到了很多AB資源打包和旋轉序列圖的功能,會在後期慢慢出教程,我們需要一步一步的學習,關於序列圖操作的拓展也會在後面講解!謝謝大家支持!


擁有自己的服務器

讓開發工作不再難

MyBe

阿里雲 —ESC服務器部署和搭建購買方式(圖文並排,一目瞭然)

一鍵領取阿里全產品2000元優惠券大禮包 (新手必得享超值優惠)


本博客爲非營利性個人原創
所刊登的所有作品的著作權均爲本人所擁有
本人保留所有法定權利,違者必究!
對於需要複製、轉載、鏈接和傳播博客文章或內容的
請及時和本博主進行聯繫,留言,Email: [email protected]
————————————————————————————————
版權聲明:對於經本博主明確授權和許可使用文章及內容的
使用時請註明文章或內容出處並註明網址
轉載請附上原文出處鏈接及本聲明。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章