Unity 基于Addressables的资源加载方案

using System;
using System.Collections;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
using UnityEngine;
using UnityEngine.AddressableAssets;
using UnityEngine.Networking;

public class ResourceManager : MonoBehaviour
{
    private static ResourceManager _instance;
    private static readonly object _lock = new object();

    public static ResourceManager Instance
    {
        get
        {
            if (_instance == null)
            {
                lock (_lock)
                {
                    if (_instance == null)
                    {
                        _instance = FindObjectOfType<ResourceManager>();

                        if (_instance == null)
                        {
                            GameObject container = new GameObject("ResourceManager");
                            _instance = container.AddComponent<ResourceManager>();
                        }
                    }
                }
            }

            return _instance;
        }
    }

    /// <summary>
    /// 异步加载本地资源
    /// </summary>
    /// <param name="address"></param>
    /// <param name="onComplete"></param>
    /// <typeparam name="T"></typeparam>
    public void LoadAssetFromLocal<T>(string address, Action<T> onComplete) where T : UnityEngine.Object
    {
        // 使用Addressables异步加载本地资源
        Addressables.LoadAssetAsync<T>(address).Completed += handle =>
        {
            if (handle.Result == null)
            {
                Debug.LogError($"Failed to load asset: {address}");
                onComplete(null);
                return;
            }
            onComplete(handle.Result);
        };
    }

    /// <summary>
    /// 加载远程资源
    /// </summary>
    /// <param name="url"></param>
    /// <param name="onComplete"></param>
    /// <typeparam name="T"></typeparam>
    public void LoadAssetFromServer<T>(string url, Action<T> onComplete) where T : class
    {
        StartCoroutine(DownloadAsset(url, (data) =>
        {
            // 将下载到的数据转换为指定类型的对象
            T asset = DeserializeBytes<T>(data);
            onComplete(asset);
        }));
    }

    /// <summary>
    /// 下载指定URL的资源并返回字节数组
    /// </summary>
    /// <param name="url"></param>
    /// <param name="onComplete"></param>
    /// <returns></returns>
    private IEnumerator DownloadAsset(string url, Action<byte[]> onComplete)
    {
        using (UnityWebRequest request = UnityWebRequest.Get(url))
        {
            yield return request.SendWebRequest(); // 发送请求,等待下载完成

            if (request.result != UnityWebRequest.Result.Success)
            {
                Debug.LogError($"Failed to download asset: {request.error}");
                onComplete(null);
                yield break;
            }

            onComplete(request.downloadHandler.data);
        }
    }

    /// <summary>
    /// 将字节数组反序列化为指定类型的对象
    /// </summary>
    /// <param name="bytes"></param>
    /// <typeparam name="T"></typeparam>
    /// <returns></returns>
    private T DeserializeBytes<T>(byte[] bytes) where T : class
    {
        if (bytes == null || bytes.Length == 0) return null;

        try
        {
            BinaryFormatter binaryFormatter = new BinaryFormatter();
            using (MemoryStream memoryStream = new MemoryStream(bytes))
            {
                T t = binaryFormatter.Deserialize(memoryStream) as T;
                return t;
            }
        }
        catch (Exception ex)
        {
            Debug.LogException(ex);
            return null;
        }
    }
}

猜你喜欢

转载自blog.csdn.net/Test_Two/article/details/129827836