游戏要做热更涉及到什么方面呢 首先就是代码热更,然后就是资源热更 这些热更新都依赖于打AssetBundle 然而打AssetBundle 你还要上传服务器-对比更新-客户端下载-加载-卸载这些流程 还有就是代码热更的一些问题 要怎么实现代码热更呢
一.对于代码热更有两个方案
1.用其他语言做热更,需要可以在C#这边创建一个lua虚拟机,于是就要和C#能够和Lua交互,C#执行lua虚拟机执行启动代码 所有逻辑用lua写 打包lua文件进行代码热更
相关C#和lua交互的框架:
1.xlua 腾讯开源框架 目前算是大家用的最多的框架,商业项目也算是用的比较多 2.tolua,slua这些比较老的框架,算不上很了解
2.C#用反射模式执行启动代码,C#打dll ,但IOS没有内存访问权限,用不了反射模式,于是有了一些绕过IOS这个机制,做反射的框架
相关C#绕过IOS做反射的框架
1.ilruntime ilruntime算是比较多人用的 以此衍生出的整套热更+资源管理框架有: QFramework,JEngine这些优秀框架 QFramework其他框架:对象池,UI,日志,音频管理,动作序列 QF更像是一个工具集合 里面可用的模块还是很多的 但是对于热更新框架来讲还是不够完整 缺了资源下载,加密,管理卸载这些东西 适用项目:做二次开发的框架
JEngine其他框架:代码加密,UI优化框架 适用项目:对于中小项目是够用的 这类框架总得来说并不是很适用大项目 少了分包管理 对于一些需要自己控制AB包 颗粒度这块 是要自己再做开发 2.huatuo 最新出的框架,在代码调用,内存占用方面是比ilruntime优秀好几倍的 市面没有基于该框架的完整热更+资源管理框架
对于C#打dll 有两个方案
1.程序集定义 优点:限制多,不用新建类库工程,代码同步方便,解耦合 缺点:dll相互调用会有相互引用的问题,自己需要在代码里面加载dll相关依赖,要分模块分的很细才行,不然每次编辑都要加载很久(有时候快有时候慢 感觉这个东西不是很稳定),然而分的很细 又要花很多时间处理父子依赖问题 相互依赖的问题解决方案: 分模块:管理器,数据,逻辑实体 例如进入一个场景 生成场景相关数据:物品,角色 这些生成逻辑由场景管理器去控制 然后把相关的数据放入到数据层 逻辑要想访问数据直接访问数据层 没有对管理层的访问权限 如果需要调用管理器的方法 直接通过回调函数进行调用 即管理器控制逻辑的初始化回调函数 这样逻辑清晰也会比较解耦合
代码加载dll依赖Assembly.LoadFrom
string gameDll = Application.streamingAssetsPath + "/LaunchClass.bytes";
gameAss = Assembly.Load(File.ReadAllBytes(gameDll));
Assembly.LoadFrom(Application.streamingAssetsPath + "/xasset.bytes");
var appType = gameAss.GetType("LaunchGame");
object o = Activator.CreateInstance(appType);
var mainMethod = appType.GetMethod("PrintTest");
mainMethod.Invoke(o, null);
适合项目:工具,方便移植模块的项目,最新的立项项目建议可以用这个 2.VS第三方类库工程 优点:自由度高,不需要额外操作,新增一个类库工程后引用相关dll就行了 缺点:代码同步麻烦,要新增工程 用法: 手动添加整块文件夹下的代码到VS工程 添加dll引用
需要注意的点:unity不同的dll库有相同的方法 如果同时using了两个库 用的时候需要声明是要用哪个库的方法 还有不要直接引用Managed下的dll 而是到下引用这些dll不然会有冲突 毕竟Managed下的dll方法并不全 需要用到子文件的dll
这个算是之前大家用的比较多的方案
二.资源管理框架
github唯一比较出名的框架:XASSET
资源管理容易出的问题:AB包加载序列化,IO占用,资源冗余,内存冗余,AB颗粒度控制
AB包加载序列化,IO占用:包体不宜太小或者太大 太小会导致加载AB包加载的(序列化内存占用) 加载和卸载的IO占用的问题(增大了硬件设备耗能和发热的压力) 最大2M不然会有加载卡顿(资源最大的就是图片,字体了 要重视这块的分包) -------------- 要分包
资源冗余: 被依赖资源没打包,然后打包时把依赖资源打进这个AB包,如果这个依赖资源被两个AB包依赖 则会多一份冗余(会被依赖打包的资源:shader 材质这些unity组件可以明确访问到的依赖,不会依赖打包的如shader或代码里面访问一个资源 shader库或其他的 ) --------------- 依赖资源打AB包
内存冗余:如果正在使用一个缓存资源(实例化出来了) 你去卸载 卸载掉了 但下次下载 再解压就会有一个内存冗余 所以卸载 需要判断这个资源是否有在使用(引用计数) 再去进行卸载 但并不是所有AB包都需要(引用计数)缓存 那样内存肯定不够用 只需要缓存经常用到的AB包 哪些不需要经常用到的AB包不考虑冗余 都是加载出来资源后立即卸载AB包
AB颗粒度控制:
要打一个包的: 角色:不然得加载十几个AB包:prefab,FBX,mat,texture2D,shader,controller,anim 会有加载卡顿和手机发热的问题 图集:不然没办法图集合批 不过好像unity有一个新出的SpriteAtlas可以用来做图集
其他可以优化注意的点:
1.对于大一点的AB包使用异步加载 避免加载卡顿 2.卸载时可以开启倒计时卸载 防止刚刚卸载就加载 3.卸载时判断这个AB包是否已经加载出来 才能卸载 4.下载时对AB资源进行标识,下载完才能关闭标识,防止下载到一半退出游戏 5.分常驻内存的包(引用计数)和加载出来资源就卸载的包
最后当热更和资源管理都做好后可以优化的点: 1.dll代码的执行速度没有il2cpp快 如果项目足够稳定 可以把基础框架 不打dll 只用xlua或者其他热修复框架来做更新 2.分包功能: 防止玩家下载AB包时间过长 弃坑 可以分包下载,即有一些功能模块是暂时可以不用下载也可以正常游戏的 需要玩家自己点下载这个包体 才下载下来才能进这个功能模块
|