Unity 热更--AssetBundle学习笔记 1.0【AB包资源加载工具类的实现】

news/2024/10/13 6:19:55

工具类封装

通过上文中对AB包加载API的了解和简单使用,对AB包资源加载的几种方法进行封装,将其写入单例类中,如代码展示。

确保每个AB资源包只加载一次:

在LoadAssetBundleManager 单例工具类中,首先提供基本的AB包及其AB包依赖包的加载方法,为保持AssetBundle只加载一次,使用DIctionary键值对来记录已经加载出的AB资源。

主包路径的灵活获取:

加载主包路径的获取,采用宏来对不同的打包平台来选择对应的主包名称。(可自行定义使用)

依赖包的加载:

通过加载主包中的AssetBundleManifest 来获取目标AB包的依赖AB包名称,根据名称进行逐个加载。

加载方法有异步和同步两种:

异步加载是在AB包获取之后进行的资源的异步加载,和同步加载一样有对加载函数进行3此重载。分别为根据名称加载,

泛型加载(C#中使用方便),根据类型加载(供Lua调用)。

卸载方法的实现:单个AB资源包卸载和所有资源包卸载两种方式。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Events;namespace BaseFramework
{/// <summary>/// 加载AssetBundle工具类 单例 /// </summary>public class LoadAssetBundleManager: SingletonAutoMono<LoadAssetBundleManager>{//主AB包 private AssetBundle mainAssetBundle = null;//包体依赖manifest private AssetBundleManifest assetBundleManifest = null;//防止AB包重复加载 对已经加载的AB包存储private Dictionary<string, AssetBundle> assetBundlesDic = new Dictionary<string, AssetBundle>();//加载路径private string pathAssetBundle{get{return Application.streamingAssetsPath + "/";}}//主包名称private string mainAssetBundleName{get{
#if UnITY_IOSreturn "IOS";
#elif UNITY_ANDROIDreturn "Android";
#elsereturn "StandaloneWindows";
#endif}}/// <summary>/// 根据名称加载AB包 也会检查相关依赖包 进行加载/// </summary>/// <param name="assetBundleName">AB包的名称</param>public void LoadAssetBundle(string assetBundleName){if (!assetBundlesDic.ContainsKey(assetBundleName)){AssetBundle resAssetBundle = AssetBundle.LoadFromFile(pathAssetBundle+assetBundleName);assetBundlesDic.Add(assetBundleName,resAssetBundle);}//加载主资源包 从主资源包中获取对manifestif (mainAssetBundle == null){mainAssetBundle = AssetBundle.LoadFromFile(pathAssetBundle + mainAssetBundleName);assetBundleManifest = mainAssetBundle.LoadAsset<AssetBundleManifest>("AssetBundleManifest");}//加载目标资源包的依赖ABstring[] dependencies = assetBundleManifest.GetAllDependencies(assetBundleName);foreach (var dependency in dependencies){AssetBundle currentAB = null;if (!assetBundlesDic.ContainsKey(dependency)){//加载依赖的ab包currentAB = AssetBundle.LoadFromFile(pathAssetBundle + dependency); assetBundlesDic.Add(dependency,currentAB);}}}/// <summary>/// 从AB包中获取具体资源/// </summary>/// <param name="abName">AB包名称</param>/// <param name="resName">资源名称</param>/// <returns>Object资源</returns>public Object LoadResource(string abName, string resName){LoadAssetBundle(abName);Object resObj = null;resObj = assetBundlesDic[abName].LoadAsset(resName);return resObj;}/// <summary>/// 泛型方法重载/// </summary>public T LoadResource<T>(string abName, string resName) where T:Object{LoadAssetBundle(abName);T res = assetBundlesDic[abName].LoadAsset<T>(resName);return res;}/// <summary>/// 根据资源类型重载方法/// </summary>public Object LoadResource(string abName, string resName, System.Type type){LoadAssetBundle(abName);Object obj = assetBundlesDic[abName].LoadAsset(resName, type);return obj;}//--------------------------------------------------------//同步加载的AB包 异步加载res资源public void LoadResourceAsync(string abName, string resName, UnityAction<Object> callback){StartCoroutine(LoadResourceIEn(abName, resName, callback));}//异步加载协程private IEnumerator LoadResourceIEn(string abName, string resName, UnityAction<Object> callback){LoadAssetBundle(abName);AssetBundleRequest request = assetBundlesDic[abName].LoadAssetAsync(resName);yield return request;callback(request.asset);}//根据泛型来异步加资源public void LoadResourceAsync<T>(string abName, string resName, UnityAction<Object> callback) where  T : Object{StartCoroutine(LoadResourceIEn<T>(abName, resName, callback));}//异步加载协程private IEnumerator LoadResourceIEn<T>(string abName, string resName, UnityAction<Object> callback) where T :Object{LoadAssetBundle(abName);AssetBundleRequest request = assetBundlesDic[abName].LoadAssetAsync<T>(resName);yield return request;callback(request.asset);}//根据res类型异步加载资源//根据泛型来异步加资源public void LoadResourceAsync(string abName, string resName, System.Type type,UnityAction<Object> callback) {StartCoroutine(LoadResourceIEn(abName, resName, type, callback));}//异步加载协程private IEnumerator LoadResourceIEn(string abName, string resName, System.Type type, UnityAction<Object> callback) {LoadAssetBundle(abName);AssetBundleRequest request = assetBundlesDic[abName].LoadAssetAsync(resName,type);yield return request;callback(request.asset);}//资源包的卸载public void UnLoadAssetBundle(string abName){if (assetBundlesDic.ContainsKey(abName)){assetBundlesDic[abName].Unload(false);assetBundlesDic.Remove(abName);}}//卸载所有加载的资源包public void UnLoadAllAssetBundle(){AssetBundle.UnloadAllAssetBundles(false);assetBundlesDic.Clear();mainAssetBundle = null;assetBundleManifest = null;}}
}

该Manager继承的单例脚本:

using UnityEngine;namespace BaseFramework
{public class SingletonAutoMono<T> : MonoBehaviour where T : MonoBehaviour{private static T instance;public static T Instance(){if (instance == null){GameObject gameObject = new GameObject();gameObject.name = typeof(T).ToString();DontDestroyOnLoad(gameObject);instance = gameObject.AddComponent<T>();}return instance;}}
}

在测试脚本中我们使用6种不同的加载方式进行cube的加载,完成方法测试。

 //测试使用工具类加载Object cube = LoadAssetBundleManager.Instance().LoadResource("model", "cube");if (cube is GameObject){GameObject cube1 = cube as GameObject;cube1.transform.position = Vector3.up;Instantiate(cube1);}//异步加载LoadAssetBundleManager.Instance().LoadResourceAsync("model", "cube", (obj) =>{GameObject cube1 = obj as GameObject;cube1.transform.position = new Vector3(0,1.5f,0);Instantiate(cube1);});//重新测试//使用泛型GameObject cube2 = LoadAssetBundleManager.Instance().LoadResource<GameObject>("model", "cube");cube2.transform.position = Vector3.left;Instantiate(cube2);LoadAssetBundleManager.Instance().LoadResourceAsync<GameObject>("model", "cube", (obj) =>{GameObject cube1 = obj as GameObject;cube1.transform.position = Vector3.right;Instantiate(cube1);});//通过类型加载测试GameObject cube3 = LoadAssetBundleManager.Instance().LoadResource("model", "cube",typeof(GameObject)) as GameObject;cube3.transform.position = new Vector3(0,-1.5f,0);Instantiate(cube3);LoadAssetBundleManager.Instance().LoadResourceAsync("model", "cube",typeof(GameObject), (obj) =>{GameObject cube1 = obj as GameObject;cube1.transform.position = Vector3.zero;Instantiate(cube1);});LoadAssetBundleManager.Instance().UnLoadAllAssetBundle();

image-20240502231345546

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.ryyt.cn/news/27085.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈,一经查实,立即删除!

相关文章

pycnblog的使用

功能一键拖拽上传 默认“未发布”,可选择直接发布 重复上传,提示是否更新博客环境 python3是需要python环境的,python的安装自己去百度一下 pycnblog的使用git clone git@github.com:dongfanger/pycnblog.gitpip install pyyaml注意 博客园6.21更新,MetaWeblog现在不支持密…

Windows中Redis怎么设置密码

Windows中Redis怎么设置密码优秀不够,你是否无可替代软件测试交流QQ群:721256703,期待你的加入!! 欢迎关注我的微信公众号:软件测试君

.Net 8.0 下的新RPC,IceRPC之使用Dev Containers进行 .NET QUIC 精简开发

作者引言很高兴啊,我们来到了IceRPC之使用Dev Containers进行 .NET QUIC 精简开发,主要是一篇指引,如何使用开发容器做为开发环境,进行开发IceRPC,可适用于任务应用的开发使用 Dev Containers 进行 .NET QUIC 精简开发主要是引导大家,如何使用开发容器Development Contain…

全网最全的nginx服务器部署-命令行_network

选用的服务器 我选用的阿文云服务器,地址是香港,优点是价格十分便宜登录 | 阿文云计算 (xn--kcr903c616a.cn)ssh登录服务器 我用的是ubuntu的里面的ssh去登录,用的虚拟机ssh -l root [你的服务器地址]ssh -l root 38.55.232.150命令的配置 安装依赖 yum install -y gcc-c+…

JDK8和JDK17共存以及切换的方法

1、先安装"jdk-8u381-windows-x64.exe",再安装"jdk-17_windows-x64_bin.exe" 2、"系统属性"-"高级"-"环境变量"-"系统变量"-"Path"-"编辑",删除以下2条 C:\Program Files\Common Files\Ora…

hgame2023 vm

vm逆向 hgame2023 vm 简单翻阅一下发现,sub_140001000里面是vm_init,sub_1400010B0是主要的vm部分查看vm_init部分,发现只知道cpu结构的大小以及初始值和24-32字节的结构,前24字节的结构未知,暂时还无法构建cpu的结构,需要更多的信息。分析下面两图的函数可以得知,opcod…

unicode编码 asis_2019_unicorn_shop

这题就是让我们购买第四个商品当我们输入price为1337.0的时候他会报错,显示要我们只输入一个字符那么我们就要想怎样用一个字符来表示一个比1337还要大的数字 答案是unicode 编码 (题目的名字给了提示) 上这个网站我们直接查看2000的unicode编码把这个编码复制一下(这就是2…