# 前言
Huatuo 是前一阵子就听说过的新的热更框架,其原理基于对 Unity il2cpp 的扩展。可以使我们目前直接打包出来的 纯 "AOT Runtime" 变成 "AOT+Interpreter" 混合 Runtime.
官方即自称为 划时代 的热更新框架,更详细的原理解释可以直接参考官方文档,这里可以简单概括两点让人感觉比较厉害的:
- 不像 XLua、ILruntime 等由于采用 VM 执行热更代码,导致需要事先做好各种处理,Huatuo 借助 il2cpp 及自己的一套指令集直接解释执行。因此可以随意调用 C# 各项特性,不需要生成代码或者写适配器。
- Huatuo 中 Unity 工作流与原生几乎完全相同,与非热更代码开发方式基本一致,非常方便。
根据官方介绍,瞬间感觉就被吸引了,于是下载下来简单试了一下。
# 说明
按照目前了解的信息,Huatuo 修改的 il2cpp 底层在加载代码之后,会判断执行的代码是否是属于 AOT,如果不是,则通过 Huatuo 解释执行 —— 而这一切都是底层的判断,而且解释执行模式又基于 il2cpp ,因此性能上理论上不用怀疑,具体性能测试相关可以查看 性能测试报告
# 安装
使用的 Unity 版本为 Unity 2021.3.0f1 , 对于 Huatuo 的安装方式,采用了方法三:使用 Unity Package Manager 安装
简单步骤如下:
- 在 Unity 中,点击 Edit->Project Settings,选择 Package Manager
- 在 Scoped Registries 中添加下面信息
- Name: package.openupm.cn
- URL: https://package.openupm.cn
- Scope(s): com.focus-creative-games.huatuo
- 点击 Apply
- 打开 Edit->Project Settings->Package Manager 界面,切换到 Window->Package Manager->Packages: My Registries 中将看到名为 huatuo Tookit for Unity 的包,直接安装即可。
注:安装并非一次性的,Huatuo 这个编辑器工具,并非 Huatuo 本身,因为 Hutuo 是直接修改替换的我们安装的 Unity 编辑器 目录下 il2cpp 文件
例如我的路径位于:Unity 2021.3.0f1\Editor\Data\il2cpp\libil2cpp
因此,安装之后可以跨项目使用,在一个项目安装之后,其它项目也会受到影响。
不过工具会自动创建 il2cpp 备份就是了,如果哪天不想用了,可以用备份还原为原始版本。
备份目录就在 Unity 安装目录下的 il2cpp 同级,例如我的是:Unity 2021.3.0f1\Editor\Data\il2cpp\libil2cpp_original_unity
# 测试 huatuo_trial 项目
# 说明
huatuo_trial 是 Huatuo 官方提供的一个示例项目。
安装完毕之后,为了先进一步认识一下,因此并没有说自己直接尝试使用,而且准备先看看官方示例项目的用法,果不其然,还是了解到有些注意点的。
# 结构
官方示例项目中,所有代码都是直接放在项目中的,不过通过创建不同的 *.asmdef 程序集描述文件,将其分类成了三个程序集,分别是:
- Main
- HotFix
- HotFix2
其中,Main 负责作为加载 HotFix 及 HotFix2 两个程序集的入口,也就是说 Main 就类似于一般游戏的 Launcher,主要用于加载、不可热更。
其中为什么在测试项目中热更 DLL 分为了两个程序集,可以看 HuaTuo_BuildProcessor_2020_1_OR_NEWER.cs 的代码,这一份貌似是作为 “配置” 存在的,里边分别标记了两者的作用:
/// <summary> | |
/// 需要在 Prefab 上挂脚本的热更 dll 名称列表,不需要挂到 Prefab 上的脚本可以不放在这里 | |
/// 但放在这里的 dll 即使勾选了 AnyPlatform 也会在打包过程中被排除 | |
/// | |
/// 另外请务必注意!: 需要挂脚本的 dll 的名字最好别改,因为这个列表无法热更(上线后删除或添加某些非挂脚本 dll 没问题) | |
/// </summary> | |
static List<string> s_monoHotUpdateDllNames = new List<string>() | |
{ | |
"HotFix.dll", | |
}; | |
/// <summary> | |
/// 所有热更新 dll 列表 | |
/// </summary> | |
public static List<string> s_allHotUpdateDllNames = s_monoHotUpdateDllNames.Concat(new List<string> | |
{ | |
// 这里放除了 s_monoHotUpdateDllNames 以外的脚本不需要挂到资源上的 dll 列表 | |
"HotFix2.dll", | |
}).ToList(); |
需要注意的是,在配置类中 OnFilterAssemblies 方法默认排除了热更程序集,如果是自己创建 DLL 文件作为游戏逻辑需要热更且放在项目中的,可能需要修改,当然跟官方一样不用额外 DLL 也可以。
根据注释说明,表示 HotFix 可以允许在 Prefab 上挂载脚本,HotFix2 则不允许,除此之外两者使用方式都是一致的,添加、删除组件都是允许的。
示例项目就展示了这一点:在 HotFix2 中创建了一个空物体,并添加了 HotFix 中的脚本。
# 测试
测试其实很简单,用 Unity 将示例项目打开之后只要不报错,只需要出包,然后随便改 HotFix、HotFix2 程序集中的代码,完了点击菜单的 Huatuo->BuildBundles->ActiveBuiuldTarget 即可。
菜单这个编辑器工具会将 Prefabs 目录下的预制体以及上述两个程序集的代码,共同打成一个叫 common 的 Bundle 文件,放在 StreamingAssets 下。
将 common 替换掉真机包的文件就可以看出效果了。
此处我在 HotFix2 App.cs、HotFix CreateByHotFix2.cs,PrintHello.cs 都随便修改了一波,基础的热更表现上都没啥问题。
虽然配置代码有注释说明,允许挂载预制体删的脚本程序集是在 AddBackHotFixAssembliesToJson 方法中打包时做了特殊处理的,
不过后边还是头铁试了下在 HotFix2 创建了一个新的 MonoBehaviour 脚本,给它直接挂载到原有的那个 HotUpdatePrefab 上,果不其然是不行的:
public class NewBehaviourScript : MonoBehaviour | |
{ | |
void Start() | |
{ | |
Debug.Log("HotFix 热更 MonoBehaviour!PrefabName:"+name); | |
} | |
} |
不过直接将其挪到 HotFix 目录下,重新出一下就可以了:
# 结语
从以上可以看出,官方将其分类为 逻辑程序集 和 Mono 程序集,估计也是像这样推荐。
使用了一下这个热更方式之后,最大的感受就是使用方式简单、接入方便,且热更代码开发方式对于开发者来说非常无感,不像其它专为热更而生的 InjectFix 或 ILRuntime,接入以及开发过程中都有不少要注意的。要不是目前官方最多支持到 Unity2019,还真想来实际试试。
要是项目可以真的推广使用就好了,因为实在不喜欢 Xlua 那些弱类型语言。
Huatuo 在知乎还开了一个知乎专栏,虽然目前文章挺少