需求:
在移动开发中,手动控制资源的加载、释放和热更新,是很有必要的。
而Unity通过AssetBundle可以实现该需求,但是如果项目资源多起来的话一个个手动打包成AssetBundle则很麻烦。
而本文正为此提供一套一键打包的方案。
资源分类、加载和实例化过程:
分类资源:
先将游戏资源分类,这里说的分类不是按资源类型(声音、贴图等)来分,而是按照打包进同一个AssetBundle的资源来分。 一般游戏按照使用频率、游戏流程、资源大小来分到不同的AssetBundle中。
举个例子:一个跑酷游戏,可将资源分为: 开始界面,主界面,关卡一资源,关卡二资源,主界面和各关卡的共享资源(如角色服装),各关卡间的共享资源(如血条,金币)。注意这里说的资源是图片,模型,声音等一些体积较大的文件。
加载资源:
游戏流程中AssetBundle的加载及卸载:
将“场景内所有GameObject”变为Prefab并打打包成AssetBundle:
在上一步中,只是将资源打包成AssetBundle,而驱动游戏进行的游戏逻辑(场景上的GameObject)则没做处理。
这样的话会导致打包出来的游戏包重复包含资源(AssetBundle和场景GameObject引用的资源重复)。
所以我们需要将场景上的GameObject也一并打包成AssetBundle,在游戏真正运行时才加载该AssetBundle并实例化。
拿unity 2d例程(2DPlatformer)做说明,即将Scene里的所有文件变为一个GameMain.Prefab,并导出为AssetBundle。
用于在之后的游戏运行后加载并实例化。
那么上一步的流程将会变为:
标记项目资源:
分类加载的思路有了,现在只差一个自动将所有资源打包成AssetBundle方法。
我们需要借助Asset Labels(Unity的标签系统)。
思路是按资源的不同分类(前文提及的分类方式),来标记每个资源。
举个例子:
上面4个资源属于关卡1的资源,因此我将他们同标记为AsRes_Level1,
他们将会一起打入AsRes_Level1.assetbundle包中,以备游戏中加载。
需要注意的是,其中AsRes_是固定标识,以便打包脚本分辨。
用这种方法则可将游戏资源一一归类。
但是,我们还有一个麻烦,就是需要先将比较笨重的资源(图片,声音,模型)先打包,然后再将驱动逻辑(例如,前面说的GameMain.Prefab)打包,
只有按这样的顺序打包才能使驱动逻辑引用到之前的打包的美术声音资源。
解决方法也比较简单,将驱动逻辑标记为AsPack_即可。
OK,就这样将整个项目的资源标记好之后就可以进行一键打包了。
例程:
为了更好的说明,我利用Unity的2DPlatformer做了一个样板工程。
其中 Editor/ResPacker.cs 是打包脚本,会在菜单Assets下新建“Build All Assets To Bundle” ,用于一键打包。
_Loader/Test_Loader.unity 是测试场景,用于加载位于StreamingAssets下的AssetBundle,并实例化‘驱动逻辑’(GameMain)。
例程下载。
注意:
在例程中有一个Bug,在编辑器中导入AssetBundle包的话,会使Sprite 上Sorting Layer变为Default,而导致图层混乱,而Build这个场景出来之后再运行则不会。