鸟语天空
StreamingAssetsLoader
post by:追风剑情 2024-6-19 15:29
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.Serialization;
/// <summary>
/// 资源加载器
/// 从 Application.streamingAssetsPath 下加载文件
/// </summary>
public class StreamingAssetsLoader : MonoBehaviour
{
    //文件url列表,只填写相对路径
    [SerializeField]
    private List<string> m_urls = new List<string>();
    //是否执行Awake方法时自动开始加载
    [SerializeField]
    private bool m_LoadOnAwake = false;

    public string url { get; private set; }
    public string error { get; private set; }
    public float progress { get; private set; }
    public AssetObject asset { get; private set; }

    [Serializable]
    public class FileProgressEvent : UnityEvent<StreamingAssetsLoader> { }
    [Serializable]
    public class FileCompletedEvent : UnityEvent<StreamingAssetsLoader> { }
    [Serializable]
    public class FileErrorEvent : UnityEvent<StreamingAssetsLoader> { }
    [Serializable]
    public class ListCompletedEvent : UnityEvent<StreamingAssetsLoader> { }

    //当前文件加载进度
    [FormerlySerializedAs("onFileProgress")]
    [SerializeField]
    private FileProgressEvent m_OnFileProgress = new FileProgressEvent();
    //当前文件加载完成
    [FormerlySerializedAs("onFileCompleted")]
    [SerializeField]
    private FileCompletedEvent m_OnFileCompleted = new FileCompletedEvent();
    //所有文件加载完成
    [FormerlySerializedAs("onListCompleted")]
    [SerializeField]
    private ListCompletedEvent m_OnListCompleted = new ListCompletedEvent();
    //当前文件加载出错
    [FormerlySerializedAs("onFileError")]
    [SerializeField]
    private FileErrorEvent m_OnFileError = new FileErrorEvent();

    public FileProgressEvent OnFileProgress => m_OnFileProgress;
    public FileCompletedEvent OnFileCompleted => m_OnFileCompleted;
    public ListCompletedEvent OnListCompleted => m_OnListCompleted;
    public FileErrorEvent OnFileError => m_OnFileError;

    //资源类型
    public enum AssetType
    {
        None = 0,//未知
        Text,   //文本
        Texture,//图片
        Audio,  //音频
        AssetBundle,  //资源包
    }

    //资源对象
    public class AssetObject
    {
        public AssetType type;
        public string url;
        public string text;
        public Texture2D texture;
        public AudioClip audioClip;
        public AssetBundle assetBundle;

        public void Dispose()
        {
            texture = null;
            audioClip = null;
            assetBundle = null;
        }
    }

    private void Awake()
    {
        if (m_LoadOnAwake)
            StartLoad();
    }

    // 清空url
    public void Clear()
    {
        m_urls.Clear();
        if (asset != null)
        {
            asset.Dispose();
            asset = null;
        }
    }

    // 设置urls
    public void SetUrls(List<string> urls)
    {
        m_urls = urls;
    }

    // 添加url
    public void AddUrl(string url)
    {
        m_urls.Add(url);
    }

    // 启动加载
    public void StartLoad()
    {
        StartCoroutine(LoadAsync());
    }

    // 停止加载
    public void StopLoad()
    {
        StopCoroutine(LoadAsync());
    }

    private IEnumerator LoadAsync()
    {
        yield return null;
        int index = 0;
        while (index < m_urls.Count)
        {
            url = m_urls[index++];
            url = string.Format("{0}/{1}", Application.streamingAssetsPath, url);
            Debug.LogFormat("Load: {0}", url);
            WWW www = new WWW(url);
            while (!www.isDone)
            {
                progress = www.progress;
                m_OnFileProgress?.Invoke(this);
                yield return www;
            }
            if (!string.IsNullOrEmpty(www.error))
            {
                error = www.error;
                m_OnFileError?.Invoke(this);
                yield break;
            }
            AssetObject obj = new AssetObject();
            obj.url = url;
            obj.type = GetAssetTypeByExtension(url);
            ReadFromWWW(obj, www);
            asset = obj;
            www.Dispose();
            m_OnFileCompleted?.Invoke(this);
            
            yield return new WaitForEndOfFrame();
        }
        m_OnListCompleted?.Invoke(this);
    }

    private void OnDestroy()
    {
        StopAllCoroutines();
    }

    // 从www中读取资源
    private void ReadFromWWW(AssetObject obj, WWW www)
    {
        switch (obj.type)
        {
            case AssetType.Text:
                obj.text = www.text;
                break;
            case AssetType.Texture:
                obj.texture = www.texture;
                break;
            case AssetType.Audio:
                obj.audioClip = www.GetAudioClip();
                break;
            case AssetType.AssetBundle:
                obj.assetBundle = www.assetBundle;
                break;
        }
    }

    // 通过后缀判断资源类型
    private AssetType GetAssetTypeByExtension(string url)
    {
        string ext = Path.GetExtension(url).ToLower();
        if (ext.Equals(".tif") || ext.Equals(".jpg") || ext.Equals(".png"))
            return AssetType.Texture;
        if (ext.Equals(".txt") || ext.Equals(".json") || ext.Equals(".xml"))
            return AssetType.Text;
        if (ext.Equals(".wav") || ext.Equals(".mp3"))
            return AssetType.Audio;
        //资源包文件后缀,根据需求定义
        if (ext.Equals(".model"))
            return AssetType.AssetBundle;
        return AssetType.None;
    }
}
评论:
发表评论:
昵称

邮件地址 (选填)

个人主页 (选填)

内容