使用 AssetBundle 进行资源按需加载
阐述如何在小游戏环境对AssetBundle进行打包、加载和内存优化。
一、AssetBundle使用
注意:小游戏环境不支持assetbundle本地加载
1.1 AssetBundle打包参数建议
c#
public static void Build()
{
string dst = Application.streamingAssetsPath + "/AssetBundles";
if (!Directory.Exists(dst))
{
Directory.CreateDirectory(dst);
}
BuildPipeline.BuildAssetBundles(dst, BuildAssetBundleOptions.AppendHashToAssetBundleName | BuildAssetBundleOptions.ChunkBasedCompression | UnityEditor.BuildAssetBundleOptions.DisableWriteTypeTree | BuildAssetBundleOptions.None, BuildTarget.WebGL);
}打包bundle时,请使用如下参数
- 【重要】BuildAssetBundleOptions.AppendHashToAssetBundleName:bundle带上hash。在小游戏底层对bundle做缓存及缓存淘汰时,hash是重要依据。
- BuildAssetBundleOptions.ChunkBasedCompression:LZ4压缩方式,加载速度和包体大小更均衡。
- 如非需要新老Unity引擎版本兼容,请使用DisableWriteTypeTree提升加载速度与降低内存。
1.2 AssetBundle下载
从服务器下载bundle的方式主要以下两种:
UnityWebRequestAssetBundle.GetAssetBundle
c#UnityWebRequest request = UnityWebRequestAssetBundle.GetAssetBundle(uriPath); yield return request.SendWebRequest(); if (request.isHttpError) { Debug.LogError(GetType() + "/ERROR/" + request.error); } else { AssetBundle ab = (request.downloadHandler as DownloadHandlerAssetBundle).assetBundle; // ab.LoadAsset ab.Unload(false); } request.Dispose();UnityWebRequest
c#UnityWebRequest www = new UnityWebRequest(uriPath); DownloadHandlerAssetBundle handler = new DownloadHandlerAssetBundle(www.uri.ToString(), 0); www.downloadHandler = handler; yield return www.Send(); if (www.isHttpError) { Debug.LogError(GetType() + "/ERROR/" + www.error); } else { AssetBundle ab = handler.assetBundle // ab.LoadAsset ab.Unload(false); } www.Dispose();特别地, 切忌使用WWW.LoadFromCacheOrDownload或WWW等带cache接口,WebGL模式下将会使用JS模拟文件系统带来额外内存消耗!
二、小游戏与APP的AssetBundle缓存更新流程差异
小游戏因其平台特殊性,需要保证加载速度,因此我们在底层对bundle文件做了缓存,开发者无须自己实现缓存。
游戏逻辑还是按照未缓存需要从网络下载去编写,插件底层会判断是否已有缓存。若未缓存则缓存此bundle;若已缓存,则返回缓存文件,实际不会发起网络请求。
在业务侧看来:总是使用异步接口从远程下载并使用,底层资源的缓存与更新已由适配层自动完成,游戏不再直接读写文件系统。
三、AssetBundle内存分析
3.1 切勿使用带Cache能力的线管接口
需要注意业务中不要使用已淘汰的WWW类,尤其WWW.LoadFromCacheOrDownload,当bundle数量多时,会浪费不少内存。
3.2 尽可能使用Unload
- 当bundle从资源服务器下载并使用,会经历多次内存分配: 浏览器HTTP对象-->拷贝到WASM临时内存-->Unity ab内存文件(略大于ab本身体积, 相对于APP常用的LoadFromFile,WebGL这部分开销是额外的)
- 当HTTP对象dispose之后,Unity ab内存文件
- 当ab.Unload时,Unity ab内存文件释放
因此,最佳实践是业务应该尽可能早地使用ab.Unload(false),自行维护Asset的引用计数管理资源。
四、部署
4.1 AB编译与部署
- 使用vivo插件导出后的最终AB资源路径如下,将webgl目录下的文件上传到CDN:

- 在插件中配置cdn路径

4.2 资源预下载
为了充分利用网络带宽,在网络空闲时可预下载游戏需要用到的AB包。详细配置请参考使用预下载功能。
