Unity-AssetBundle
什么是AssetBundle
AssetBundle定义
AssetBundle是Unity中的一个资源压缩包,它可以包括模型、纹理、预设、场景或者更新文件,它可以在运行的过程中被加载,目的就是减少我们打包后的包体积。
它是一个存在于硬盘上的文件。可以称之为压缩包。这个压缩包可以认为是一个文件夹,里面包含了多个文件。这些文件可以分为两类:serialized file 和 resource files。(序列化文件和源文件)
serialized file:资源被打碎放在一个对象中,最后统一被写进一个单独的文件(只有一个)
resource files:某些二进制资源(图片、声音)被单独保存,方便快速加载,可以Editor上读取,方便查看。
除了本地也可以使用它进行网络加载,即把打包后的AssetBundle放到服务器上作为更新的资源,例如宣传的主题图片,玩家进行游戏的时候发现有资源更新就可以直接从服务器端下载,很方便。
压缩算法
压缩包可以使用LZMA和LZ4压缩算法,下面是两种压缩算法的对比:
lzma的下载速度比lz4的速度要快。
运行时加载开销lz4要优于lzma。
在使用LoadFromFile(Async)加载lzma格式的AB包时,内存的占用会是资源文件内存的大约2倍,而使用lz4则是跟资源文件内存大小一致的。
lz4无论是解压时间、加载开销和内存占用都优于lzma,但唯一的缺点就是包体会大不少(约25%)左右。所以如果想要包体小,且加载速度又快,我们可以使用GZip把资源在打包完之后再打个压缩包,这样的话包体也会小很多。
使用代码打包
我们可以在资源的Inspector面板下放给设置自定义的文件夹和后缀名 其中后缀名可以是自己任意起名,这样在打包后的文件夹下可以看到自定义的文件夹。
接着我们创建一个脚本,代码如下。
using UnityEditor;
using System.IO;
public class CreateAssetBundles
{
[MenuItem("Assets/Build AssetBundles")]
static void BuildAllAssetBundles()
{
string assetBundleDirectory = "Assets/AssetBundles";
if(!Directory.Exists(assetBundleDirectory))
{
Directory.CreateDirectory(assetBundleDirectory);
}
BuildPipeline.BuildAssetBundles(assetBundleDirectory,
BuildAssetBundleOptions.None,
BuildTarget.StandaloneWindows64);
}
}
代码的意思是在我们项目的根目录的Assets下创建个目录AssetsBundles目录在这里生成我们的压缩包。
关于编译器的代码一定要放在Editor下面,否则报错说找不到命名空间。
加载资源
创建代码如下
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class LoadFromAB : MonoBehaviour
{
void Start()
{
AssetBundle ab = AssetBundle.LoadFromFile("Assets / AssetBundles/cube.ab");
//CubePre是cube的预制体的名字
GameObject myCube = ab.LoadAsset<GameObject>("CubePre");
Instantiate(myCube);
}
}
上面代码的意思就是把我们之前打包的cube加载出来并且实例化。
如果我们加载的物体有依赖别的物体,像一个预制体和他的材质的关系,我们需要先把他的依赖的东西解压出来,举一个例子:有一个Cube他上面有材质,材质引用了贴图,解压时需要在解压Cube之前把材质和贴图先解压出来,其中材质和贴图的解压顺序可以不用考虑先解压谁都可以。这是文档中给出的,但测试的时候无论何时解压都可以正常显示,所以我们还是尽量先解压依赖项。
打包策略
1.把经常更新的资源放到一个包里,与不经常更新的资源分离。
2.把需要同时加载的资源放到一个包里。
3.可以把其他包共享的资源放在一个单独的包里。
4.把一些需要同时加载的小资源放到一个包里。
5.对于同一个资源有两个版本可以通过考虑后缀来区分。