Unity AssetBundles资源加载管理器

Unity AssetBundles资源加载管理器

实现了AB包管理器

目的: 让外部更方便地进行资源加载(同步加载/异步加载)

技术包含:

  1. AB包相关API
  2. 单例模式
  3. 委托(Lambda)表达式
  4. 协程
  5. 字典

AssetBundles工具下载地址

csharp 复制代码
using System.Collections;
using System.Collections.Generic;
using Unity.VisualScripting;
using UnityEngine;
using UnityEngine.Events;


/// <summary>
/// AB 包管理器
/// 目的: 让外部更方便地进行资源加载
/// 包含
/// 1. AB包相关API
/// 2. 单例模式
/// 3. 委托(Lambda)表达式
/// 4. 协程
/// 5. 字典
/// </summary>
public class ABMgr : SingletonAutoMono<ABMgr>
{

    //主包
    private AssetBundle mainAB = null;
    //依赖包获取的配置文件
    private AssetBundleManifest manifest= null;

    //字典  用字典来存储 加载过的AB包
    private Dictionary<string, AssetBundle> abDic = new Dictionary<string, AssetBundle>();

    //AB包存放路径
    private string PathUrl
    {
        get
        {
            return Application.streamingAssetsPath+"/";
        }
    }

    //主包名
    private string MainABName
    {
        get
        {
            #if UNITY_IOS
                    return "IOS";
            #elif UNITY_ANDROID
                    return "Android";
            #else
                    return "PC";
            #endif


        }
    }
    /// <summary>
    /// 加载ab包
    /// </summary>
    /// <param name="abname"></param>

    private void LoadAB(string abname)
    {
        //加载AB包
        if (mainAB == null)
        {
            mainAB = AssetBundle.LoadFromFile(PathUrl + MainABName);
            manifest = mainAB.LoadAsset<AssetBundleManifest>("AssetBundleManifest");
        }
        //获取abname包的依赖信息,根据依赖信息添加依赖包
        AssetBundle ab = null;
        string[] strs = manifest.GetAllDependencies(abname);
        for (int i = 0; i < strs.Length; i++)
        {
            //判断包是否加载过了
            if (!abDic.ContainsKey(strs[i]))
            {
                ab = AssetBundle.LoadFromFile(PathUrl + strs[i]);
                abDic.Add(strs[i], ab);
            }
        }
        //加载资源来源包,如果没有加载过再加载
        if (!abDic.ContainsKey(abname))
        {
            ab = AssetBundle.LoadFromFile(PathUrl + abname);
            abDic.Add(abname, ab);
        }
    }
    //同步加载 根据名字
    public Object LoadRes(string abname,string resname)
    {
        //加载ab包
        LoadAB(abname);

        //加载资源
        //为了方便外面加载 判断资源是否为GameObect
        //如果是 直接实例化 再返回给外部
        Object obj = abDic[abname].LoadAsset(resname);
        if (obj is GameObject)
        {
            return Instantiate(obj);
        }
        else return obj;
    }

    //同步加载 根据type
    public Object LoadRes(string abname, string resname,System.Type type)
    {
        //加载ab包
        LoadAB(abname);

        //加载资源
        //为了方便外面加载 判断资源是否为GameObect
        //如果是 直接实例化 再返回给外部
        Object obj = abDic[abname].LoadAsset(resname,type);
        if (obj is GameObject)
        {
            return Instantiate(obj);
        }
        else return obj;
    }

    //同步加载 泛型
    public T LoadRes<T>(string abname, string resname) where T: Object
    {
        //加载ab包
        LoadAB(abname);

        //加载资源
        //为了方便外面加载 判断资源是否为GameObect
        //如果是 直接实例化 再返回给外部
        T obj = abDic[abname].LoadAsset<T>(resname);
        if (obj is GameObject)
        {
            return Instantiate(obj);
        }
        else return obj;
    }

    /// <summary>
    /// 异步加载(Async) 根据名字
    /// 加载AB包没有使用异步
    /// 而是加载AB包中的asset资源的时候使用异步
    /// </summary>
    /// <param name="abname"></param>
    public void LoadResAsync(string abname, string resname,UnityAction<Object> callBack)
    {
       
        StartCoroutine(ReallyLoadAsync(abname,resname,callBack));
    }
   
    private IEnumerator ReallyLoadAsync(string abname,string resname,UnityAction<Object> callBack)
    {
        //加载AB包
        LoadAB(abname);

        //创建请求 从AB包加载资源
        AssetBundleRequest abr = abDic[abname].LoadAssetAsync(resname);
      
        //等待abr加载结束
        yield return abr;
        //abr.asset 为加载的资源
        if(abr.asset is GameObject)
        {
            //abr如果是GameObject 实例化
            callBack(Instantiate(abr.asset));
        }else
        {
            callBack(abr.asset);
        }

    }

    /// <summary>
    /// 异步加载(Async) 根据type
    /// </summary>
    /// <param name="abname"></param>

    public void LoadResAsync(string abname, string resname,System.Type type, UnityAction<Object> callBack)
    {

        StartCoroutine(ReallyLoadAsync(abname, resname,type, callBack));
    }

    private IEnumerator ReallyLoadAsync(string abname, string resname, System.Type type,UnityAction<Object> callBack)
    {
        //加载AB包
        LoadAB(abname);

        //创建请求 从AB包加载资源
        AssetBundleRequest abr = abDic[abname].LoadAssetAsync(resname,type);

        //等待abr加载结束
        yield return abr;
        //abr.asset 为加载的资源
        if (abr.asset is GameObject)
        {
            //abr如果是GameObject 实例化
            callBack(Instantiate(abr.asset));
        }
        else
        {
            callBack(abr.asset);
        }

    }


    /// <summary>
    /// 异步加载(Async) 泛型
    /// </summary>
    /// <param name="abname"></param>
    public void LoadResAsync<T>(string abname, string resname, UnityAction<T> callBack) where T : Object 
    {
		
		// public delegate void UnityAction<T0>(T0 arg0);
		//其中UnityAciton是有着一个参数(T0)的委托
        StartCoroutine(ReallyLoadAsync<T>(abname, resname, callBack));
    }

    private IEnumerator ReallyLoadAsync<T>(string abname, string resname, UnityAction<T> callBack) where T: Object 
    {
        //加载AB包
        LoadAB(abname);
	
        //创建请求 从AB包加载资源
        AssetBundleRequest abr = abDic[abname].LoadAssetAsync<T>(resname);

        //等待abr加载结束
        yield return abr;
        //abr.asset 为加载的资源
        if (abr.asset is GameObject)
        {
            //abr如果是GameObject 实例化
            //最后回调函数(函数指针,函数作为参数)调用委托
            callBack(Instantiate(abr.asset) as T);
        }
        else
        {
            callBack(abr.asset as T);
        }

    }

    //单个包卸载
    public void Unload(string abname)
    {
        if (abDic.ContainsKey(abname))
        {
            abDic[abname].Unload(false);
            abDic.Remove(abname);
        }
    }
    //所有包卸载
    public void ClearAB()
    {
        //卸载所有AssetBundles(UnloadAll)
        AssetBundle.UnloadAllAssetBundles(false);
        //清空字典
        abDic.Clear();
        //主包和配置文件置空
        mainAB = null;
        manifest = null;
    }

}
相关推荐
张晓~1833994812116 小时前
短视频矩阵源码-视频剪辑+AI智能体开发接入技术分享
c语言·c++·人工智能·矩阵·c#·php·音视频
lrh302518 小时前
Custom SRP - Point and Spot Lights
unity·srp·render pipeline
almighty2718 小时前
C# DataGridView表头自定义设置全攻略
数据库·c#·winform·datagridview·自定义表头
绀目澄清18 小时前
unity UGUI 鼠标画线
unity·计算机外设·游戏引擎
Magnum Lehar19 小时前
3d wpf游戏引擎的导入文件功能c++的.h实现
3d·游戏引擎·wpf
作孽就得先起床19 小时前
unity pcd 二进制版 简单显示文件对象(单色)
unity·游戏引擎
arbboter20 小时前
【自动化】深入浅出UIAutomationClient:C#桌面自动化实战指南
运维·c#·自动化·inspect·uiautomation·uia·桌面自动化
文弱书生65621 小时前
5.后台运行设置和包设计与实现
服务器·开发语言·c#
大飞pkz1 天前
【设计模式】题目小练2
开发语言·设计模式·c#·题目小练
csdn_aspnet1 天前
MongoDB C# .NetCore 驱动程序 序列化忽略属性
mongodb·c#·.netcore