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;
    }

}
相关推荐
向宇it36 分钟前
【blender小技巧】Blender导出带贴图的FBX模型,并在unity中提取材质模型使用
开发语言·unity·c#·游戏引擎·blender·材质·贴图
Bartender_Jill2 小时前
【Claude AI大语言模型连接Blender生成资产】Windows安装Blender MCP教程
人工智能·语言模型·json·游戏引擎·blender
大模型铲屎官3 小时前
# Unity动画控制核心:Animator状态机与C#脚本实战指南 (Day 29)
c语言·unity·c#·游戏引擎·游戏开发·动画控制·animator状态机
安全菜鸟3 小时前
DeepSeek 接入 Word 完整教程
开发语言·c#·word
vil du4 小时前
c# AI编程助手 — Fitten Code
开发语言·c#·ai编程
努力长头发的程序猿4 小时前
UnityUI:Canvas框架获取鼠标悬浮UI
unity·c#
zxy28472253015 小时前
.NET MAUI教程2-利用.NET CommunityToolkit.Maui框架弹Toast
c#·.net·maui·toolkit.maui
liwulin05065 小时前
【WORD】批量将doc转为docx
开发语言·c#·word
围垦7 小时前
C# visionpro联合编程中遇到的问题之 R6025 - pure virtual function call
数码相机·c#·visual studio
码观天工8 小时前
.NET 原生驾驭 AI 新基建实战系列(三):Chroma ── 轻松构建智能应用的向量数据库
ai·c#·.net·向量数据库