作用
- 是一个压缩包,包含模型、贴图、预制体、场景等资源,可以在游戏运行时被加载。
- 自身保存相互依赖的关系
- 减少安装包的大小,资源有需加载
- 也可以被认为是一个文件夹,可以包含序列化文件和源文件,序列化文件例如预制体和模型,一个AB包中只有一个序列化文件,源文件例如声音和图片,可以有多个。
使用流程
- 设置AB包属性
- 构建AB包
- 上传AB包
- 加载AB包和资源
构建AB包
常用压缩选项有三种
- BuildAssetBundleOptions.None。LZMA算法压缩,压缩率最高,下载第一次加载后会使用LZ4算法重新压缩。
- BuildAssetBundleOptions.ChunkBasedCompression。LZ4算法压缩,可以解压部分资源。
- BuildAssetBundleOptions.UncompressedAssetBundle。不压缩。
BuildPipeline.BuildAssetBundles(dir, BuildAssetBundleOptions.None, BuildTarget.StandaloneWindows64);
依赖打包是由Unity编辑器自动完成的,在依赖打包前应该设置好各个资源的AB属性。
加载AB包
//一个包cubewall.unity3d,包含材质、贴图、预制体CubeWall
AssetBundle ab = AssetBundle.LoadFromFile("AssetBundles/cubewall.unity3d");
GameObject wallPrefab = ab.LoadAsset<GameObject>("CubeWall");
Instantiate(wallPrefab);
//加载依赖
//两个包cubewall.unity3d和share.unity3d
//cubewall.unity3d,包含材质、贴图
//share.unity3d,包含预制体CubeWall
AssetBundle ab = AssetBundle.LoadFromFile("AssetBundles/cubewall.unity3d");
AssetBundle.LoadFromFile("AssetBundles/share.unity3d");
GameObject wallPrefab = ab.LoadAsset<GameObject>("CubeWall");
Instantiate(wallPrefab);
//利用AssetBundles.manifest文件加载依赖
//两个包cubewall.unity3d和share.unity3d
//cubewall.unity3d,包含材质、贴图
//share.unity3d,包含预制体CubeWall
AssetBundle manifestAB = AssetBundle.LoadFromFile("AssetBundles/AssetBundles");
AssetBundleManifest manifest= manifestAB.LoadAsset<AssetBundleManifest>("AssetBundleManifest");
string[] dependencies = manifest.GetAllDependencies("cubewall.unity3d");
foreach(string s in dependencies)
{
AssetBundle.LoadFromFile(Path.Combine("AssetBundles", s));
}
ab = AssetBundle.LoadFromFile("AssetBundles/cubewall.unity3d");
GameObject wallPrefab = ab.LoadAsset<GameObject>("CubeWall");
Instantiate(wallPrefab);
卸载AB对象
AssetBundle.Unload(False)
这个函数会卸载AB对象及加载的不需要使用的资源,并切除AB对象和当前在使用资源,例如M的联系,当再次加载AB包时,即使内存中有M,也会重新在AB对象中生成一个新的P,这样M对象就无法卸载,导致内存出问题。此时调用AssetBundle.LoadAsset()就会重新生成M对象的一个新实例。
AssetBundle.Unload(True)
这个函数会将整个AB对象及其加载的资源完全卸载掉。
对于AssetBundle.Unload(False)卸载资源方式残留下的Asset对象M,可以先将M引用置为Null,然后再调用以下方式卸载。
//第一种方式
Resources.UnloadUsedAssets()
//第二种方式
//以非增加的方式切换场景,这时候会自动调用
Resources.UnloadUsedAssets()