C#hybridCLR热更新方案初探

前言

暂时处于初步研究状态,目前的框架使用还是尚少,本篇文章旨在同步给大家大概的使用流程和使用心得,在初步建立新项目时可以适当考虑。

介绍

热更新

与强制更新相对应,移动平台上App的可执行程序没有发生变化,仅需要更新游戏资产就可以实现新版本的分发,这种更新称之为热更新。由于不需要经过App商店审核,这种更新内容可以非常快速地分发给玩家。玩家也不需要重新下载App全量包,仅需要下载变动的资产部分即可正常进行游戏,相对而言减小了玩家流失的风险。

为什么会诞生第三方热更新方案,而非系统原生支持

IOS上的反射是部分支持,支持使用反射读取源代码,但不支持使用反射动态生成可执行代码。总而言之,IOS不支持以动态方式创建新的方法和类型。资源热更新采用我们目前的assetbundle是没有任何问题的,如果我们把部分逻辑提取至一个单独的代码库工程中,打包为DLL,再用DLL打包成AB包,用户下载完这个AB包后动态加载DLL文件,按理说是可行的,但是ios不支持动态运行代码,所以是没办法的。

第三方热更新方案

目前市面上主流的,我了解到的热更新方案有lua、ILRunTime、HybridCLR。

从unity到底层二进制代码的流程主要是Unity->.net字节码->il2cpp->C++静态代码->二进制代码

lua分xlua和ulua。xlua是腾讯写的lua热更新框架,目前项目在使用,主要逻辑是自己会生成一个虚拟机管理lua数据,在初始阶段用dostring或者loader的方式加载lua,中期通过挂载luabehaviour的方式和lua侧的luatable进行交流,中间有关unity的obj生成wrap文件让lua侧能get、set数据。具体参考前文Lua与C#交互初析-CSDN博客

ILRuntime项目为基于C#的平台(例如Unity)提供了一个纯C#实现,快速、方便且可靠的IL运行环境,使得能够在不支持JIT的硬件环境(如iOS)能够实现代码的热更新。由于unity可以解释执行.net字节码,所以ilruntime采取C#侧的一个虚拟环境来对C#代码作.net字节码更新,交给unity。

HybridCLR改写了il2cpp模块,给il2cpp新增了原生的interpreter模块,使其能够通过Assembly.Load的方式动态加载dll。没有数据跨域的问题。

df1e45504d8d4588a3f8d298038911a1.png

简要概括,为了能让游戏运行过程中动态更新代码,有两种流派:lua和ILRuntime在unity内部实现一个虚拟机,用虚拟机解释执行.net代码,在这里面进行代码热更;hybridCLR改写了更底层的il2cpp模块,我们在运行时只需要确保更新到最新的.dll模块,即可完成代码更新。

HybridCLR操作流程

AssetBundle

在说明代码热更新之前,首先需要研究AB包的热更新流程。打包方式采用BuildPipeline.BuildAssetBundles实现,在运行过程中调用AB包资源时采用AssetBundle.LoadFromFile/AssetBundle.LoadFromMemoryAssetBundle.LoadAsset实现。

下载

为了模拟热更新,客户端本地需要在网络上请求到最新的资源并且下载到本地,再用新下载的文件加载进游戏中才算真正实现。于是服务器端我临时搭建了一个python的http服务器用来处理简单的上传下载功能。客户端采用项目里的下载流程。

HybridCLR框架使用

根据官方文档的流程做,新建一个2021稳定版本的unity工程,在内部安装HybridCLR package并初始化HybridCLR,并对playerSettings做出一些改动(比如关闭增量式GC(Use Incremental GC) 选项、Scripting Backend 切换为 il2cpp等操作)。具体流程参照官方文档

在进程刚启动时就更新主链接库Assembly-CSharp.dll,参考以下代码,时间类似于项目组目前的startup更新,只不过这里更新的是dll文件,组内更新的是assetbundle然后解包注入lua bytes。

1a3496dea7b54bf1adc15a358a7e2104.png

30d5247c09834e14832e0d779a5095b2.png

553ec0647f334b12877f7fa3bd5561a0.png

load完Assembly-CSharp.dll就直接开始走内部加载方式了,直接在热更新的代码片段里驱动调用更新代码把其他资源更新过来即可。

acc68c8db8d44064afdac94944453292.png

最后就可以开展其他工作了,比如在这些资源上增删改查代码。

更新前:

a505c7f19f6847a8bce313d6500b7cca.png

7552543b5bc44ed4867e590b2d1530d5.png

更新后:

4dce3a9035234d2ebf451c32bd7ffe19.png

aabdb465e81b4ec681b7908763d2a8d1.png

如果后期要增加外部dll(大部分时候用Assembly-CSharp.dll就已经可以了),也没啥问题,直接在热更新C#代码里更新热更资源就行。比如现在我增加一个新的dll,只需要导入进来并且设置project的HybridCLR settings即可(类似assetbundle kit设置)。

dcafe7cebca44d8fb754c79be282070a.png

导入ClassLibrary1.dll后改写上述的hotupdatemain即可。

013366bcd61c4f68a8b3b00fbc9d64b8.png

04bdf8725c1343929f3871378f2ca533.png

这个时候不用换包,还是用之前的那个包,依然可以达到热更新效果。

8bf0a14848524afd9b71480f5219e5f8.png

 

  • 28
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值