Unity 使用AssetBundle-Browser打包助手
转载:Unity 打包与加载AssetBundle(加载对应的依赖)
一、AssetBundle-Browser简介
AssetBundle-Browser是Unity3D的一个可视化的打包工具,可以用来快速直观的对资源进行压缩打包,有些版本的Unity可以直接从Window->Package Manage下载,没有的可以从下面连接下载,下载后直接导入项目即可:
导入资源后,可以从Window-AssetBundle Browser打开窗口。界面如下:
二、简单的单个压缩(无依赖:即不复用资源)
1、新建一个预制体,例如下图,再给它一个AssetBundle标签audio,点击一下助手左上角的刷新,则标签为audio的预制体就会出现(也可以直接拖进来)。
2、接下来,切换到Build栏,设置好发布平台和路径,(一般也会选择复制到StreamingAssets文件夹中,方便加载调用)就可以点击Build进行压缩了。
3、压缩完后,在Project窗口中右键刷新,就可以在StreamingAssets文件夹中看到压缩过的文件。其中StandaloneWindows文件只会出现这两个,后面再压缩其他文件不会再出现,只会产生两个压缩过的文件。
4、压缩文件的加载
(1)我们来试下加载刚压缩的这个音频文件,新建脚本AssetBundleLoaderMgr,代码如下(该代码不需要挂载,后面直接调用的):
using UnityEngine; using System.Collections; using System.Collections.Generic; using System.IO; public class AssetBundleLoaderMgr { /// <summary> /// 初始化,加载AssetBundleManifest,方便后面查找依赖 /// </summary> public void Init() { string streamingAssetsAbPath = Path.Combine(Application.streamingAssetsPath, "StandaloneWindows"); AssetBundle streamingAssetsAb = AssetBundle.LoadFromFile(streamingAssetsAbPath); m_manifest = streamingAssetsAb.LoadAsset<AssetBundleManifest>("AssetBundleManifest"); } /// <summary> /// 加载AssetBundle /// </summary> /// <param name="abName">AssetBundle名称</param> /// <returns></returns> public AssetBundle LoadAssetBundle(string abName) { AssetBundle ab = null; if (!m_abDic.ContainsKey(abName)) { string abResPath = Path.Combine(Application.streamingAssetsPath, abName); ab = AssetBundle.LoadFromFile(abResPath); m_abDic[abName] = ab; } else { ab = m_abDic[abName]; } return ab; } /// <summary> /// 从AssetBundle中加载Asset /// </summary> /// <typeparam name="T">类型</typeparam> /// <param name="abName">AssetBundle名</param> /// <param name="assetName">Asset名</param> /// <returns></returns> public T LoadAsset<T>(string abName, string assetName) where T : Object { AssetBundle ab = LoadAssetBundle(abName); T t = ab.LoadAsset<T>(assetName); return t; } /// <summary> /// 缓存加载的AssetBundle,防止多次加载 /// </summary> private Dictionary<string, AssetBundle> m_abDic = new Dictionary<string, AssetBundle>(); /// <summary> /// 它保存了各个AssetBundle的依赖信息 /// </summary> private AssetBundleManifest m_manifest; /// <summary> /// 单例 /// </summary> private static AssetBundleLoaderMgr s_instance; public static AssetBundleLoaderMgr instance { get { if (null == s_instance) s_instance = new AssetBundleLoaderMgr(); return s_instance; } } }
(2)调用加载,进行测试:把该代码挂载在物体上,输入要加载对象的AssetBundle标签名跟预制体名即可。
using System.Collections; using System.Collections.Generic; using UnityEngine; public class Main : MonoBehaviour { [Header("标签名:")] public string assetBundle; [Header("预制体名:")] public string prefabName; void Awake() { //初始化 AssetBundleLoaderMgr.instance.Init(); } void LoadAsset() { //加载预设 GameObject prefab = AssetBundleLoaderMgr.instance.LoadAsset<GameObject>(assetBundle, prefabName); //实例化预设 Instantiate(prefab); } void OnGUI() { if (GUI.Button(new Rect(100, 100, 100, 50), "LoadAsset")) { LoadAsset(); } } }
三、资源复用
当然,在实际项目中我们会遇到多个预制体有相同的部分,要是一个一个压缩,还是有点浪费资源,所以我们可以把共同的部分单独作为一个AssetBundle进行压缩,其他不同的部分再各自压缩就好了。所以,这样其他不同的部分就会跟这个共同部分产生一个依赖,我们要加载的时候,也必须把依赖加载上,不然就会造成资源丢失,不是原本的预制体的效果。
那么来试一下。
1、再新建个预制体Audio1,新标签audio1,用刚才的那个背景音乐,这样的话,Audio与Audio1有共同的资源song。
2、拖入之后,我们会看到有感叹号出现,是因为有共同的资源song,我们可以在左侧栏右键,新建一个bundle,命名为res,把共用的素材放进去,再一起打包即可。
3、这样就简单实现了资源复用,可以看到,audio和audio1都对res产生了依赖关系,所以加载audio或audio1时,也要把res加载进去,这样才完整。
4、资源加载
(1)我们试一下上面所用的代码,不加载依赖,只加载audio,看看效果
会发现,Audio Source的AudioClip丢失了,这就是因为没有把依赖的res文件夹加载上来。
(2)所以,要加载完整,我们可以对上面的AssetBundleLoaderMgr脚本加上加载依赖的代码,如下所示
//加载依赖 string[] dependences = m_manifest.GetAllDependencies(abName); int dependenceLen = dependences.Length; if (dependenceLen > 0) { for (int i = 0; i < dependenceLen; i++) { string dependenceAbName = dependences[i]; if (!m_abDic.ContainsKey(dependenceAbName)) { AssetBundle dependenceAb = LoadAssetBundle(dependenceAbName); m_abDic[dependenceAbName] = dependenceAb; } } }
把这一段放入AssetBundleLoaderMgr脚本的如下位置,其他不做改变。
(3)再来验证一下,这里就加载上来了。
(4)两个audio的最终加载效果
以上,如有疑问,欢迎来共同探讨,一起进步!