AssetBundle是什么?
AssetBundle是一个存档文件,包含可运行时加载的特定于平台的资源(模型、纹理、预制体、场景)
AssetBundle可以表达彼此之间的依赖关系,AssetBundle A中的材质可以引用AssetBundle B中的纹理
为通过网络进行有效传递,可以根据用例要求选用内置算法来压缩(LZMA,LZ4)
LZMA算法:压缩的包更小,加载时间更长。使用之前需要整体解压。一旦被解压,这个包会使用LZ4重新压缩。这时候使 用资源的时候不需要整体解压。
LZ4算法:加载时间与不压缩相近,使用前不用整体解压。
1.用于可下载内容,减小初始安装大小。
2.加载针对于最终用户平台优化的资源,减轻运行时内存压力
3.需要更新一些简单的东西,如节日活动的UI需要更改之类的,可以使用AssetBundle包去更新而不需要用户重新下载游戏
AssetBundle中有什么?
包含磁盘上的实际文件,称为AssetBundle存档,可以视为一个容器,可以在其中包含其他的文件。这些文件分为两类:
1.serialized file(序列化文件):资源被打碎放在一个对象中,最后统一被写进一个单独的文件(只有一个)
resource files(源文件):资源文件只是为某些资源(纹理,音频)单独存储的二进制数据块,允许我们有效地在另一个线程上从磁盘上加载它们
2.AssetBundle对象:通过代码从一个特定的压缩包中加载出来的对象,此对象包含了所有我们当初添加到这个压缩包里面的内容,我们可以通过这个对象加载出来使用
AssetBundle使用流程:
1.指定资源的AssetBundle属性
在要打包的资源的Inspector面板中指定AssetBundle的属性
2.构建AssetBundle包
创建Editor文件夹,在文件夹中创建一个C#脚本,代码为:
using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEditor; using System.IO; public class CreateAssetBundles{ /*MenuItem属性允许你添加菜单项到主菜单和检视面板上下文菜单。 该属性把任意静态函数变为一个菜单命令。仅静态函数能使用这个MenuItem属性*/ [MenuItem("Assets/Build AssetBundles")] static void BulidAllAssetBundles() { string dir = "AssetBundles"; if (Directory.Exists(dir) == false) Directory.CreateDirectory(dir); //输出路径 打包压缩格式 打包到的平台 BuildPipeline.BuildAssetBundles(dir, BuildAssetBundleOptions.None, BuildTarget.StandaloneWindows64); } }
BuildAssetBundleOptions.None:使用LZMA算法压缩
BuildAssetBundleOptions.UncompressedAssetBundle:不压缩,包大,加载快 BuildAssetBundleOptions.ChunkBasedCompression:使用LZ4压缩
通过 MenuItem我们在Unity的Asset选项中创建了Bulid AssetBundles选项调用此代码将资源打包到dir指定的目录中
在项目的文件中就可以看到我们打包出来的AssetBundles包了
游戏发布后需要AssetBundle包在服务器上,这时我们才需要游戏从服务器下载AssetBundle包进行加载,开发时因为需要进行频繁的调试,我们将包放在本地来进行加载
3.在本地对AssetBundle进行加载和使用:游戏场景中创建空物体挂载脚本,内容为:
using System.Collections; using System.Collections.Generic; using UnityEngine; public class LoadWallFormFile : MonoBehaviour { // Use this for initialization void Start () { //1.加载AssetBundle AssetBundle ab = AssetBundle.LoadFromFile("AssetBundles/wall.dz"); //2.从AssetBundle中取得要加载的资源 GameObject wallPrefab = ab.LoadAsset<GameObject>("Wall"); //3.把资源实例化到场景当中 Instantiate(wallPrefab); } }
这样就可以在场景中看到之前我们打包好的东西了
AssetBundle分组策略:
指定资源的AssetBundle标签其实就是一种对资源的分类
1.经常更新的资源放在一个单独的包,与不经常更新的包分离
2.需要同时加载的资源(小资源)放在一个包里
3.其它包共享的资源放在一个包中(减小AB包的大小)
4.同一个资源有两个版本可以考虑通过后缀来区分对于第三点,存在共享的资源怎么进行依赖打包的案列:
如图场景中存在一个sphere和cube,都使用了名为wood的材质
假如我们没有采用依赖打包,那么就会出现下图中左边的情况,AB包中为sphere和cube打包的文件中,包含着一样的贴图和材质,如果我们采用右边的依赖打包方案,就能对包的大小进行一个优化
首先将要共用的贴图和材质的AssetBundle设为share
再为cube和sphere分别设置一个AssetBundle的属性,名字随意
观察再次打包出来的文件,cube和sphere的文件大小都很小了,share的大小是最大的
而如果没有对要共用的资源设置AssetBundle的标签的话,打包出来就会如下图一样,cube和sphere中都含有一套一样的贴图和材质