热更新技术,是当前网络游戏的一项必要功能, 在此只讨论Assetbundle资源的更新, 不讨论代码的更新。
一、进行资源梳理切分,哪些资源是独立性较好的,依赖链清晰的,可以归纳到一个包的,把资源依赖的层级关键画好。
二、将资源分为两大类,一类为内置Resources资源,一类为Assetbundle资源
内置Resources资源或者叫AssetsLibrary,由Unity自行管理,不能进行更新(或者说不能直接修改)。
而Assetbundle资源为加部自定义加载项,可以进行更新。
三、Assetbundle资源打包
BuildPipeline.PushAssetDependencies();
var options = = BuildAssetBundleOptions.CollectDependencies
| BuildAssetBundleOptions.UncompressedAssetBundle
| BuildAssetBundleOptions.DeterministicAssetBundle;
BuildPipeline.BuildAssetBundle(.., "base.unity3d", options)
BuildPipeline.BuildAssetBundle(.., "level.unity3d", options)
BuildPipeline.PopAssetDependencies();
这样一来, level.unity3d 与 base.unity3d 中重复的资源, 将打在base.unity3d 中, level.unity3d 将不会重复打包此资源
四、加载Assetbundle资源
// 只需一句即可
AssetBundle.CreateFromFile(...)
完成
下面说一下需要注意的地方:
一、可以写一个交叉引用的扫描工具,扫描Assetbundle与Resources交叉引用的资源,这部分资源会被重复打包,浪费了空间,内存,效率。所以可以进行文件调整
二、注意打包选项 BuildAssetBundleOptions.UncompressedAssetBundle, 如果要使用Assetbundle.CreateFromFile,必须要使用这个选项,打包后的文件比较大,但是没办法,是不压缩的。
三、注意打包选项BuildAssetBundleOptions.DeterministicAssetBundle,这是Unity的一个坑爹选项,官方文档中有以下描述
... if you have a lot of objects in the asset bundle it will increase the potential for hash conflicts. Unity will give an error and not build the asset bundle in that case...
如果发生打包失败的情况(曾经碰到过,报hash collision错误),那么可能有以下几种解决方案(不是and的关系,是or的关系):
1、去掉这个选项,将所有的Assetbundle依赖包全部更新
2、手工改一下这个冲突资源的GUID试一下(修改方式很简单,去改meta文件)
3、分包,原来是2000个文件一个Assetbundle包,现在切为2个Assetbundle文件,一个包1000个文件
4、联系Unity公司解决