需求描述
在加载一个AssetBundle资源包(后续简称AB包)的时候我们还需要考虑其对应的依赖,所以加载AssetBundle资源包并非总是简单地调用相关的加载API即可,缺乏依赖那么AssetBundle资源包中的资源就无法正常加载或使用。
通过AssetBundle加载相关的API无法直接获取对应的.manifest文件内容,例如有一个AB包叫“ABTest“,那么默认情况下与之对应的清单文件名称则为” ABTest.manifest”,那么我们希望获取ABTest这个资源包的相关信息,就需要加载ABTest.manifest文件,而AssetBundle加载相关的API只能用于加载AB包文件,但是通过AssetBundle Brower插件中的Inspect界面我们可以查看到Main AssetBundle(代指主AB包,并非固定为此名称)中包含了一个名为”AssetBundleManifest”的资源,实际上这个AssetBundleManifest中就包含了与Main AssetBundle一起打包的其它AB包的依赖信息,换言之就是将当前所有AB包的依赖信息整合到了一起,只需要通过AssetBundleManifest就可以获取到当前所有AB包的依赖信息。《官方手册》
使用示例
首先通过AssetBundle Brower插件构建AB包合集,打包好之后的目录如图1所示。
在图1所示目录结构中,SLWindows即为Main AssetBundle,audioclips、prefabs、sprites分别为存储了音频文件、预制体文件、Sprite文件的AB包,为了方便测试,这些AB包与它们的清单文件都拷贝到了Unity项目的Assets/StreamingAssets目录下。虽然SLWindows是主AB包,但它与其它AB包并不是根节点和子节点的关系,SLWindows中仅仅是记录了其它AB包的依赖信息,并不能直接通过它获取其它AB包。
在prefabs中有两个预制体,分别依赖于audioclips中的音频文件和sprites中的Sprite文件,接下来我们就来探索如何正确加载prefabs中的两个预制体。
首先创建一个测试脚本,在Start方法中编写以下代码:
using System.IO;
using UnityEngine;
public class Test : MonoBehaviour
{
void Start()
{
//加载SLWindows
AssetBundle v_mainAB = AssetBundle.LoadFromFile(Path.Combine(Application.streamingAssetsPath, "SLWindows"));
//加载AssetBundleManifest
AssetBundleManifest v_abm = v_mainAB.LoadAsset<AssetBundleManifest>("AssetBundleManifest");
//获取prefabs中的依赖信息
string[] v_dependencies = v_abm.GetAllDependencies("prefabs");
//通过依赖信息加载依赖的AB包
foreach (string abName in v_dependencies)
{
AssetBundle.LoadFromFile(Path.Combine(Application.streamingAssetsPath, abName));
}
//加载prefabs这个AB包
AssetBundle v_prefabs = AssetBundle.LoadFromFile(Path.Combine(Application.streamingAssetsPath, "prefabs"));
//加载prefabs中的资源prefaba和prefabb
GameObject v_prefabA = v_prefabs.LoadAsset<GameObject>("prefaba");
GameObject v_prefabB = v_prefabs.LoadAsset<GameObject>("prefabb");
//测试代码:将prefaba和prefabb的实例分别创建出来
Instantiate(v_prefabA);
Instantiate(v_prefabB);
}
}
通过LoadFromFile同步加载Unity项目Assets/StreamingAssets目录下的SLWindows这个主AB包,然后通过LoadAsset加载其中的AssetBundleManifest,再通过GetAllDependencies获取prefabs这个AB包的所有依赖信息,通过依赖信息结合LoadFromFile加载所有依赖的AB包,最后加载prefabs这个AB包,然后通过LoadAsset加载prefabs中的资源。
F&Q
Q1.依赖分为直接依赖和间接依赖,如果prefabs中存在间接依赖的资源怎么办?
A1.实际上这就是AssetBundleManifest中GetAllDependencies和GetDirectDependencies的区别,前者是获取直接依赖和间接依赖的所有AB包,后者仅获取直接依赖的AB包,所以我们通常使用前者。
Q2.AssetBundleManifest是固定名称吗?是否可以更改?
A2.这个名称是固定的,目前据我所知只能通过这个名称来获取AssetBundleManifest对象,但是这个名称不区分大小写,既可以是"AssetBundleManifest"也可以是"assetbundlemanifest",或者"Assetbundlemanifest"等,结合如图2所示就能够明白了。
如果这篇文章对你有帮助,请给作者点个赞吧!