这一篇主要讲的只有一个点,就是关于AB打包时的压缩方式的选择。
第一篇中,打包的代码中有一句是
BuildPipeline.BuildAssetBundles(RES_OUTPUT_PATH, BuildAssetBundleOptions.ChunkBasedCompression, BuildTarget.StandaloneWindows64);
BuildAssetBundleOptions:
None : 没有任何特殊要求。
UncompressedAssetBundle : 不压缩。
DisableWriteTypeTree : Assetbundle中不包含Type信息。TypeTree将在后面提到。
DeterministicAssetBundle : 使用资源的Hash ID来导出AssetBundle。使用ID可避免资源改名、移动位置等导致重新导出。
ForceRebuildAssetBundle : 强制重新导出。对已有的AssetBundle,在资源没有变化时,Unity不会重新导出。
IgnoreTypeTreeChanges : 增量打包时忽略Type信息变化。
AppendHashToAssetBundleName : 在AssetBundle名称后添加”_”加上Hash值。
ChunkBasedCompression : 使用块压缩,即LZ4压缩。
Unity为我们提供了三种压缩策略来处理AB的压缩,LZMA格式,LZ4格式,不压缩。
LZMA格式:
在默认情况下,打包生成的AB都会被压缩。标准压缩格式便是LZMA(LZMA是一种序列化流文件),因此在默认情况下(BuildAssetBundleOptions.None),打出的AssetBundle包处于LZMA格式的压缩状态,在使用AssetBundle前需要先解压缩。使用LZMA格式压缩的AssetBundle的包体积最小(高压缩比),但是相应的会增加解压缩时的时间。
LZ4格式:
Unity 5.3之后的版本增加了LZ4格式压缩,由于LZ4的压缩比一般,因此经过压缩后的AssetBundle包体的体积较大(该算法基于chunk)。但是,使用LZ4格式的好处在于解压缩的时间相对要短。若要使用LZ4格式压缩,只需要在打包的时候开启BuildAssetBundleOptions.ChunkBasedCompression即可。
不压缩:
当然,我们也可以不对AssetBundle进行压缩。没有经过压缩的包体积最大,但是访问速度最快。若要使用不压缩的策略,只需要在打包的时候开启BuildAssetBundleOptions.UncompressedAssetBundle即可。
配图即为相同的Asset在三种方式打包后,生成AB包的大小,大家可以直接试试看。
关于上述压缩方式以及之后使用AB时候,相关的占用空间,内存消耗等网上找的一张图:
注意:当使用WWW来下载一个bundle时,WebRequest还会有一个8*64KB的缓存区用来存储来自socket的数据。
建议:
1. 随游戏一同发布的AssetBundle(一般位于StreamingAssets文件夹中):在打AssetBundle包时,使用LZ4压缩格式进行打包(ChunkBasedCompression)。在运行时需要加载AssetBundle对象时,使用LoadFromFile方法进行加载。这样做的好处是:即可以将AssetBundle文件压缩,又可以兼顾加载速度,且节约内存。
2. 作为更新包,需要从服务端下载的AssetBundle:在打AssetBundle包时,使用默认的LZMA格式压缩。使用WWW.LoadFromCacheOrDownload方法下载并缓存AssetBundle包文件。这样做的好处是:获得了最大的压缩率,在下载过程中可以减少数据传输量。同时,在本地磁盘创建缓存之后,又可以兼顾之后的加载速度,且节约内存。
3. 我们自己进行加密的AssetBundle:在打AssetBundle包时,使用LZ4压缩格式进行打包(ChunkBasedCompression)。在运行时需要加载AssetBundle对象时,使用LoadFromMemory方法进行加载。(这也是从内存中使用流数据加载AssetBundle对象的仅有的使用场景。)
4. 我们自己压缩的AssetBundle:我们自己也可以使用第三方库或工具对生成的AssetBundle包文件进行压缩,如果需要这样做,则我们最好不要再使用Unity3D对AssetBundle进行压缩,因此在打包时选择开启UncompressedAssetBundle。在运行时需要加载AssetBundle对象时,使用LoadFromFileAsync方法进行异步加载。
BuildTarget:
常用的即:BuildTarget.iOS,BuildTarget.Android,BuildTarget.StandaloneWindows64三个,不用说大家也应该理解吧。代码里可以用EditorUserBuildSettings.activeBuildTarget去读取Unity当前平台的编译环境。
下一篇将会讲讲依赖相关的。