当前位置: 首页 > news >正文

Unity AB包加载与依赖管理全解析

如何将资源与AB包进行关联

选择资源 在Inspector窗口最下方的AssetBundle处点击new填写一个名称

那么你在Window下的AssetBundle Browser中就可以看到你所关联的AB包

进行打包

Build Target 是打包的平台,不同的平台需要重新打包

Output Path是输出的路径,Application.dataPath下的AssetBundles/PC

Clear Folders 是否需要情况文件夹,可以删除一些没有用的资源,但随着项目往后资源越多打包越慢

Copy to StreamingAssets 打包后拷贝到SteamingAssets目录下

NoCompression 不压缩 解压快 包大 不推荐

LZMA 压缩最,解压慢 缺点用一个资源要解压所有

LZ4 压缩相对于LZMA大一点,建议使用,用什么解压什么,内存占用低

AB包生成的文件

AB包-资源文件

manifest文件- AB包文件信息和当加载时提供了关键信息,资源信息,依赖关系,版本信息等等

关键AB包(和目录名一样的包) - 主包,AB包依赖关键信息

代码控制加载AB包资源

using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class lesson2_1 : MonoBehaviour
{// Start is called before the first frame updatevoid Start(){//加载AB包(AB包不能重复加载否则报错)AssetBundle ab = AssetBundle.LoadFromFile(Application.streamingAssetsPath + "/model");//加载AB包中的资源//GameObject obj = ab.LoadAsset<GameObject>("Cube");//GameObject obj2 = ab.LoadAsset("Sphere",typeof(GameObject)) as GameObject;//Instantiate(obj, Vector3.zero, Quaternion.identity);//Instantiate(obj2);StartCoroutine(LoadABRes("model","Cube"));//卸载所有加载的AB包 参数为true  会把通过AB包加载的资源也卸载//AssetBundle.UnloadAllAssetBundles(false);//ab.Unload(false);}IEnumerator LoadABRes(string ABName, string resName){AssetBundleCreateRequest abcr = AssetBundle.LoadFromFileAsync(Application.streamingAssetsPath+"/"+ABName);yield return abcr;AssetBundleRequest abr = abcr.assetBundle.LoadAssetAsync<GameObject>("Cube");yield return abr;GameObject obj = abr.asset as GameObject;Instantiate(obj);}// Update is called once per framevoid Update(){}
}

关于AB包的依赖

一个资源身上用到了别的AB包中的资源 这个时候如果只加载自己的AB包,通过它创建对象 会出现资源丢失的情况

这种时候 需要把依赖包 一起加载才能正常

比如:给立方体关联了一个材质球

但材质球和立方体并不属于一个AB包

这样当我们加载model的ab包中的立方体时,场景上的立方体就会丢失材质

解决方案

利用主包 获取依赖信息

       //加载AB包(AB包不能重复加载否则报错)AssetBundle ab = AssetBundle.LoadFromFile(Application.streamingAssetsPath + "/model");//加载AB包中的资源GameObject obj = ab.LoadAsset<GameObject>("Cube");//GameObject obj2 = ab.LoadAsset("Sphere",typeof(GameObject)) as GameObject;Instantiate(obj, Vector3.zero, Quaternion.identity);//Instantiate(obj2);//加载主包AssetBundle abMain = AssetBundle.LoadFromFile(Application.streamingAssetsPath + "/PC");//加载主包中的固定文件AssetBundleManifest abmanifest = abMain.LoadAsset<AssetBundleManifest>("AssetBundleManifest");//从固定文件中 得到依赖信息string[] strs = abmanifest.GetAllDependencies("model");//得到了依赖包的名字for (int i = 0; i < strs.Length; i++){ AssetBundle.LoadFromFile(Application.streamingAssetsPath + "/"+strs[i]);}

结果

AB包资源管理器


using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Events;public class ABMgr:MonoBehaviour
{private static ABMgr instance;public static ABMgr Instance => instance;private void Awake(){instance = this;}private AssetBundle mainAB = null;private AssetBundleManifest manifest = null;private string PathUrl{get {return Application.streamingAssetsPath + "/";}}private string MainABName{get {
#if UNITY_IOSreturn "IOS";
#elif UNITY_ANDROIDreturn  "Android";
#elsereturn  "PC";
#endif}}public  Dictionary<string,AssetBundle> abDic = new Dictionary<string,AssetBundle>();//同步加载private void LoadAB(string abName){//如果没有加载过主包,先加载主包if (mainAB == null && !abDic.ContainsKey(MainABName)){mainAB = AssetBundle.LoadFromFile(PathUrl + MainABName);abDic.Add(MainABName, mainAB);manifest = mainAB.LoadAsset<AssetBundleManifest>("AssetBundleManifest");}//从主包的关键配置文件中获取依赖信息AssetBundle ab = null;string[] strs = manifest.GetAllDependencies(abName);for (int i = 0; i < strs.Length; i++){//判断和abName有依赖的ab包是否加载过,没加载需要加载并存入字典if (!abDic.ContainsKey(strs[i]))abDic.Add(strs[i], AssetBundle.LoadFromFile(PathUrl + strs[i]));}//判断需要的ab包是否有加载过,没加载再加载if (!abDic.ContainsKey(abName)){ab = AssetBundle.LoadFromFile(PathUrl + abName);abDic.Add(abName, ab);}}//同步加载 不指定类型public Object LoadRes(string abName, string resName){LoadAB(abName);//返回加载的资源return abDic[abName].LoadAsset(resName);}//同步加载 根据type指定类型public Object LoadRes(string abName, string resName,System.Type type){LoadAB(abName);//返回加载的资源return abDic[abName].LoadAsset(resName,type);}//同步加载 根据泛型指定类型public T LoadRes<T>(string abName, string resName) where T : Object{LoadAB(abName);//返回加载的资源return abDic[abName].LoadAsset<T>(resName);}//异步加载public void LoadResAsync(string abName, string resName, UnityAction<Object> callBack){StartCoroutine(ReallyLoadResAsync(abName,resName,callBack));}private IEnumerator ReallyLoadResAsync(string abName, string resName, UnityAction<Object> callBack){LoadAB(abName);AssetBundleRequest abr = abDic[abName].LoadAssetAsync(resName);yield return abr;callBack(abr.asset);}public void LoadResAsync(string abName, string resName,System.Type type, UnityAction<Object> callBack){StartCoroutine(ReallyLoadResAsync(abName, resName, type, callBack));}private IEnumerator ReallyLoadResAsync(string abName, string resName, System.Type type, UnityAction<Object> callBack){LoadAB(abName);AssetBundleRequest abr = abDic[abName].LoadAssetAsync(resName,type);yield return abr;callBack(abr.asset);}public void LoadResAsync<T>(string abName, string resName, UnityAction<T> callBack) where T : Object{StartCoroutine(ReallyLoadResAsync<T>(abName, resName, callBack));}private IEnumerator ReallyLoadResAsync<T>(string abName, string resName, UnityAction<T> callBack) where T: Object{LoadAB(abName);AssetBundleRequest abr = abDic[abName].LoadAssetAsync<T>(resName);yield return abr;callBack(abr.asset as T);}//单个包卸载public void Unload(string abName){if (abDic.ContainsKey(abName)){abDic[abName].Unload(false);abDic.Remove(abName);}}//所有包的卸载public void ClearAB(){AssetBundle.UnloadAllAssetBundles(false);abDic.Clear();mainAB = null;manifest = null;}}

测试代码:

        ABMgr.Instance.LoadResAsync("model", "Cube", (obj) =>{Instantiate(obj, Vector3.up, Quaternion.identity);});ABMgr.Instance.LoadResAsync("model", "Cube", (obj2) =>{Instantiate(obj2, -Vector3.up, Quaternion.identity);});ABMgr.Instance.LoadResAsync("model", "Cube", (obj3) =>{Instantiate(obj3, Vector3.right, Quaternion.identity);});

结果

http://www.dtcms.com/a/486108.html

相关文章:

  • 基于Springboot的游戏网站的设计与实现45nuv3l8(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。
  • 深入理解 Vue.js 原理
  • 基于bert-base-chinese的外卖评论情绪分类项目
  • OpenSSL EVP编程介绍
  • 网站服务器组建中国国际贸易网站
  • 上新!功夫系列高通量DPU卡 CONFLUX®-2200P 全新升级,带宽升 40% IOPS提60%,赋能多业务场景。
  • Spring Boot 3零基础教程,properties文件中配置和类的属性绑定,笔记14
  • 以数据智能重构 OTC 连锁增长逻辑,覆盖网络与合作生态双维赛跑
  • 【推荐100个unity插件】基于节点的程序化无限地图生成器 —— MapMagic 2
  • 71_基于深度学习的布料瑕疵检测识别系统(yolo11、yolov8、yolov5+UI界面+Python项目源码+模型+标注好的数据集)
  • 工控机做网站服务器网络模块
  • Mac——文件夹压缩的简便方法
  • Playwright自动化实战一
  • 电商网站开发面临的技术问题做seo网站诊断书怎么做
  • 【Qt】QTableWidget 自定义排序功能实现
  • WPF 疑点汇总2.HorizontalAlignment和 HorizontalContentAlignment
  • 【Qt】3.认识 Qt Creator 界面
  • 垂直网站建设付费小说网站怎么做
  • PDFBox - PDDocument 与 byte 数组、PDF 加密
  • 【Pytorch】分类问题交叉熵
  • 如何轻松删除 realme 手机中的联系人
  • Altium Designer怎么制作自己的集成库?AD如何制作自己的原理图库和封装库并打包生成库文件?AD集成库制作好后如何使用丨AD集成库使用方法
  • Jackson是什么
  • 代码实例:Python 爬虫抓取与解析 JSON 数据
  • 襄阳建设网站首页百度知识营销
  • 山东住房和城乡建设厅网站电话开发软件都有哪些
  • AbMole| Yoda1( M9372;GlyT2-IN-1; Yoda 1)
  • LLM监督微调SFT实战指南(Qwen3-0.6B-Base)
  • 【基础算法】多源 BFS
  • *@UI 视角下主程序与子程序的菜单页面架构及关联设计