前言
Unity资源的热更新就是AssetBundle,这是手游开发的初学者必经之路。而且Unity官方也说明最好不要用Resource文件夹加载资源了,所以现在我们就来看看Gameframework的Resource模块到底写了什么,浅析一下此模块的原理。
1.Resource模块初探
首先需要将EditorResourceMode取消勾选,这样变成从AssetBundle包加载游戏资源。默认情况下是编辑器的资源加载模式,是用AssetDatabase去直接从路径加载资源的,所以我们先找到Builtin下的BaseComponent组件设置好资源加载模式,如下图所示:
这个设置好以后,接下需要把资源打成资源包,然后就可以启动游戏断点调试了,启动游戏之后我们可以在Resource下找到一些挂载的脚本,我们可以从这里慢慢深挖资源模块的实现,Resource下有Load Resource Agent Helper挂载了DefaultLoadResourceAgentHelper脚本。 可以在这个脚本看到加载资源的函数是ReadFile和ReadByte,ReadByte主要是用来加载经过加密的二进制文件,然后在Update里面去轮回AssetBundleCreateRequest参数获取资源,但是我们需要看看框架是如何调用ReadByte或者ReadFile。发现是有一个任务代理池里面有Web请求代理,下载代理,资源加载代理等等。框架会不断的轮询任务池,当我们调用ResourceComponent类下的LoadAsset函数时,就是创建了加载资源代理添加到任务池中。资源加载模块的基本原理就是这样子的。接下来我再介绍一下ResourceComponent的Load Resource Agent Helper Count这个参数,如图所示:
这个参数是控制Resource下Load Resource Agent Helper的个数,也就是DefaultLoadResourceAgentHelper实例化的个数,这个主要可以说是来控制资源加载速度的,为什么这么说呢?因为比如你的游戏资源加载属于爆发形式,一个场景需要一口气加载10多个Asset Bundle包,这样建议你最好把这个参数调大点。因为任务池在轮询任务时,发现DefaultLoadResourceAgentHelper实例都还在加载中或者还在占用中,没有进行Reset。没有空闲的代理实例时,这样就会进行等待加载资源。也就是其他资源需要加载时会被挂起,如图所示:
当然并不是越大越好...你需要知道游戏加载资源的阀值,合理去设置Load Resource Agent Helper Count的个数。
2.框架实现了什么?
首先我们生成一下GameForwork.Dll的Resource模块的项目依赖图,发现ResourceManager是核心的类,Resource模块的回调还是挺多的,关系依赖图如下:
在ResourceManager看到有功能是场景加载,其他资源加载,资源解密,资源卸载,资源版本更新等等,所继承的接口有IResourceManager,IResourceGroup,IResourceHelper,ILoadResourceAgentHelper。
IResourceGroup是资源组接口,可以获取资源组的参数的一些API,资源为什么要分组管理呢?比如某个模块的资源更新或者其他的,整体管理可以更加方便等等。
IResourceManager是资源管理器接口,缓存资源组和已经加载过的资源。可以获取资源的版本编号和相关的路径地址,还有一些版本更新和资源加载的函数等等。
IResourceHelper是资源辅助器接口,从指定文件路径读取数据流,卸载场景,释放资源。
ILoadResourceAgentHelper是加载资源代理辅助器接口,加载资源会伴随六大事件(异步加载资源更新事件,异步读取资源文件完成事件,异步读取资源二进制流完成事件,异步将资源二进制流转换为加载对象完成事件,异步加载资源完成事件,错误事件)。资源的文件和二进制异步加载还有重置辅助器的函数。是实际加载资源的接口,加载完成以后会缓存到ResourceManager下ResourceLoader的IObjectPool。