依赖关系
分别为材质和Prefab设置不同的AseetBundle名,如图:
执行打包命令后,将得到6个文件:
其中,materials和prefabs文件对应了我们设置的AB名,那么前两个AssetBundles文件是用来干什么呢?其实这个文件就是用来存放资源信息和依赖关系,打开AssetBundles.manifest可以看到一些详细的信息:
可以在Info_1的位置看到,prefabs的依赖(Dependencies)有: materials。
不加载依赖会怎么样
查看prefab的Inspector面板可以发现,其中的MeshRender引用了材质Wood1,如果从AB包中加载这个prefab,而不加载材质会发生什么了,先来做一个验证。代码如下:
using System.Collections;
using UnityEngine;
using UnityEngine.Networking;
public class AssetBundleTest : MonoBehaviour
{
private void Awake()
{
Load();
}
private void Load()
{
AssetBundle prefabAB = AssetBundle.LoadFromFile("Assets/AssetBundles/prefabs");
GameObject wood1 = prefabAB.LoadAsset<GameObject>("Wood1");
Instantiate(wood1);
}
}
把上面的代码挂到场景中的物体上运行后发现,虽然场景中成功创建了Wood1物体,但是物体的材质却丢失了。
prefabs和materials中的资源依赖,可以用以下的图来说明:
在这种情形下,在加载prefabs之前必须先加载materials(使用前)。
如何获取依赖
如果手动来加载依赖,是否可行呢?当然可行,只不过太过麻烦,随着资源的增多,依赖关系也会越来越复杂,这种方法显然不太合适。回到打包可以发现,打包过程中,除了生成对应的AB包之外,还会生成两个额外的文件。这两个文件就存放着我们需要的依赖信息,通过它们就能获取到对应的资源依赖信息了。代码如下:
using System.Collections;
using UnityEngine;
using UnityEngine.Networking;
public class AssetBundleCube : MonoBehaviour
{
private void Awake()
{
Load();
}
private void Load()
{
//加载并获取Manifest
AssetBundle manifestAB = AssetBundle.LoadFromFile("Assets/AssetBundles/AssetBundles");
AssetBundleManifest manifest = manifestAB.LoadAsset<AssetBundleManifest>("AssetBundleManifest");
//从Manifest中获取依赖信息并加载依赖
string[] depends = manifest.GetAllDependencies("prefabs");
for (int i = 0; i < depends.Length; i++)
{
AssetBundle.LoadFromFile("Assets/AssetBundles/" + depends[i]);
}
//从prefabs包中加载并创建Wood1
AssetBundle prefabAB = AssetBundle.LoadFromFile("Assets/AssetBundles/prefabs");
GameObject wood1 = prefabAB.LoadAsset<GameObject>("Wood1");
Instantiate(wood1);
}
}
将上面的代码挂到场景中的物体上运行可以发现,场景中成功加载出了Wood1物体,并且这次材质没有丢失