# 前言

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 安装

简单步骤如下:

  1. 在 Unity 中,点击 Edit->Project Settings,选择 Package Manager
  2. 在 Scoped Registries 中添加下面信息
    • Name: package.openupm.cn
    • URL: https://package.openupm.cn
    • Scope(s): com.focus-creative-games.huatuo
  3. 点击 Apply
  4. 打开 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 的代码,这一份貌似是作为 “配置” 存在的,里边分别标记了两者的作用:

s
/// <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 在知乎还开了一个知乎专栏,虽然目前文章挺少