Addressable资源加载框架

代码:

using UnityEngine.AddressableAssets;
using UnityEngine.AddressableAssets.Initialization;
using UnityEngine.ResourceManagement.AsyncOperations;
using UnityEngine;
using System.Collections.Generic;
using System;

class BaseLoader
{
    protected string name = string.Empty;

    private AsyncOperationHandle handle;

    private bool isLoad = false;
    public BaseLoader(string name)
    {
        this.name = name;
        this.isLoad = false;
    }

    /// <summary>
    /// 加载资源
    /// </summary>
    /// <param name="name">资源名称</param>
    /// <param name="parent">加载完成之后存放的父节点</param>
    /// <param name="onComplete">加载完成之后的回调</param>
    public virtual void Load<T>(Action<T> onComplete) where T : UnityEngine.Object
    {
        if (this.isLoad)
        {
            if (handle.IsDone)
            {
                if (onComplete != null)
                {
                    onComplete(handle.Result as T);
                }
            }
            else
            {
                handle.Completed += (result) =>
                {
                    if (result.Status == UnityEngine.ResourceManagement.AsyncOperations.AsyncOperationStatus.Succeeded)
                    {
                        var obj = result.Result as T;
                        if (onComplete != null)
                        {
                            onComplete(obj);
                        }
                    }
                    else
                    {
                        if (onComplete != null)
                        {
                            onComplete(null);
                        }
                        Debug.LogError("Load name = " + name + " tpye = " + typeof(T).ToString() + " failed!  ");
                    }
                };
            }
        }
        else
        {
            this.isLoad = true;
            this.handle = Addressables.LoadAssetAsync<T>(name);
            handle.Completed += (result) =>
            {
                if (result.Status == UnityEngine.ResourceManagement.AsyncOperations.AsyncOperationStatus.Succeeded)
                {
                    var obj = result.Result as T;
                    if (onComplete != null)
                    {
                        onComplete(obj);
                    }
                }
                else
                {
                    if (onComplete != null)
                    {
                        onComplete(null);
                    }
                    Debug.LogError("Load name = " + name + " tpye = " + typeof(T).ToString() + " failed!  ");
                }
            };
        }
    }

    /// <summary>
    /// 同步方法加载资源
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <returns></returns>
    public virtual T Load<T>() where T : UnityEngine.Object
    {
        this.isLoad = true;
        this.handle = Addressables.LoadAssetAsync<T>(name);
        T obj = this.handle.WaitForCompletion() as T;
        this.isLoad = false;
        return obj;
    }

    /// <summary>
    /// 同时加载多个资源
    /// </summary>
    /// <typeparam name="T"></typeparam>
    public virtual List<T> Loads<T>() where T : UnityEngine.Object
    {
        this.isLoad = true;
        this.handle = Addressables.LoadAssetsAsync<T>(name, (obj) => { });
        List<T> objs = this.handle.WaitForCompletion() as List<T>;
        return objs;
    }

    public virtual void Release()
    {
        if (this.isLoad)
        {
            this.isLoad = false;
            Addressables.Release(handle);
        }
    }
}

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
/// <summary>
/// 预制类资源加载器
/// </summary>
class GameObjectLoader : BaseLoader
{
    /// <summary>
    /// 资源缓存列表
    /// </summary>
    private Stack<GameObject> caches = new Stack<GameObject>();

    /// <summary>
    /// 正在使用的列表
    /// </summary>
    private HashSet<GameObject> references = new HashSet<GameObject>();


    public GameObject prefab;

    public GameObjectLoader(string name) : base(name)
    {
        this.prefab = null;
    }

    public GameObjectLoader(GameObject obj) : base(obj.name)
    {
        this.prefab = obj;
    }
    /// <summary>
    /// 同步方法,确保已经加载好了
    /// </summary>
    /// <param name="parent"></param>
    /// <returns></returns>
    public GameObject Instantiate(Transform parent)
    {
        GameObject obj = null;
        if (caches.Count > 0)
        {
            obj = caches.Pop();
        }
        else
        {
            obj = GameObject.Instantiate(this.prefab) as GameObject;
            obj.name = this.name;
        }
        this.references.Add(obj);
        return obj;
    }

    /// <summary>
    /// 同步方法实例化对象
    /// </summary>
    /// <returns></returns>
    public GameObject Instantiate()
    {
        if (caches.Count > 0)
        {
            var obj = caches.Pop();
            this.references.Add(obj);
            return obj;
        }
        else
        {
            if (this.prefab != null)
            {
                var obj = GameObject.Instantiate(this.prefab) as GameObject;
                obj.name = this.name;
                this.references.Add(obj);
                return obj;
            }
            else
            {
                this.prefab = base.Load<GameObject>();
                var obj = GameObject.Instantiate(this.prefab) as GameObject;
                obj.name = this.name;
                base.Release();
                this.references.Add(obj);
                return obj;
            }
        }
    }

    public void Free(GameObject obj)
    {
        this.caches.Push(obj);
        this.references.Remove(obj);
        obj.transform.SetParent(AssetManager.Instance.PoolRoot);
    }


    public override void Release()
    {
        foreach (var obj in this.caches)
        {
            GameObject.Destroy(obj.gameObject);
        }
        if (this.references.Count <= 0)
        {
            base.Release();
            AssetManager.Instance.RemovePools(this.name);
        }
    }

}

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.AddressableAssets;
using UnityEngine.AddressableAssets.Initialization;
/// <summary>
/// 全局单例资源管理器
/// 所有的资源加载最终都走此类入口
/// </summary>
public class AssetManager
{
    private static AssetManager assetManager;
    public static AssetManager Instance
    {
        get
        {
            if (assetManager == null)
            {
                assetManager = new AssetManager();
            }
            return assetManager;
        }
    }

    #region Prefab 预制加载管理
    /// <summary>
    /// 缓存对象根节点
    /// </summary>
    public UnityEngine.Transform PoolRoot;

    private Dictionary<string, GameObjectLoader> pools = new Dictionary<string, GameObjectLoader>();
    /// <summary>
    /// 缓存查找表
    /// </summary>  
    private Dictionary<GameObject, GameObjectLoader> lookup = new Dictionary<GameObject, GameObjectLoader>();

    public AssetManager()
    {
        UnityEngine.Transform poolNode = new GameObject("[Asset Pool]").transform;
        poolNode.transform.localPosition = Vector3.zero;
        poolNode.transform.localScale = Vector3.one;
        poolNode.transform.localRotation = Quaternion.identity;
        GameObject.DontDestroyOnLoad(poolNode);
        //启动定时器,定时清理缓存池里的缓存
    }

    /// <summary>
    /// 同步实例化GameObject
    /// </summary>
    /// <param name="name"></param>
    /// <returns></returns>
    public GameObject Instantiate(string name)
    {
        GameObjectLoader loader;
        if (this.pools.TryGetValue(name, out loader))
        {
            var obj = loader.Instantiate();
            this.lookup.Add(obj, loader);
            return obj;
        }
        else
        {
            loader = new GameObjectLoader(name);
            var obj = loader.Instantiate();
            //添加缓存池
            this.pools.Add(name, loader);
            //添加缓存查找表
            this.lookup.Add(obj, loader);
            return obj;
        }
    }

    /// <summary>
    ///获取模板信息
    /// </summary>
    /// <param name="name"></param>
    /// <returns></returns>
    public GameObject GetTemplete(string name)
    {
        GameObjectLoader loader;
        if (this.pools.TryGetValue(name, out loader))
        {
            return loader.prefab;
        }
        return null;
    }

    /// <summary>
    /// 将资源释放回缓存池
    /// </summary>
    /// <param name="obj"></param>
    public void FreeGameObject(GameObject obj)
    {
        GameObjectLoader loader;
        if (this.lookup.TryGetValue(obj, out loader))
        {
            loader.Free(obj);
            //释放后从缓存查找表中移除
            this.lookup.Remove(obj);
        }
    }

    public void RemovePools(string name)
    {
        this.pools.Remove(name);
    }
    ///由定时器调用,定时清理缓存,一般设计为10分钟清理一次
    public void ReleaseAll()
    {
        foreach (var item in this.pools.Values)
        {
            item.Release();
        }
    }

    #endregion
}

转载自:https://blog.csdn.net/qq_19428987/article/details/119353314

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值