Unity + HybirdCLR热更新 入门篇

news2025/6/5 4:58:53

官方文档

HybridCLR | HybridCLRhttps://hybridclr.doc.code-philosophy.com/docs/intro

什么是HybirdCLR?

        HybridCLR(原名 huatuo)是一个专为 Unity 项目设计的C#热更新解决方案,它通过扩展 IL2CPP 运行时,使其支持动态加载和运行 .NET 程序集(Assembly),从而在保持高性能的同时实现代码热更新能力。

        HybridCLR 最初的名字 "huatuo"(华佗) 来源于中国古代名医 华佗 的典故,寓意这个技术能像神医一样为 Unity 项目 "治病"(修复Bug) 和 "强身"(动态更新功能),而无需重新发布版本。后来为了国际化推广,项目改名为 HybridCLR:

Hybrid(混合):代表它结合了 AOT(IL2CPP) + Interpreter(解释执行) 两种模式。

CLR(Common Language Runtime):表明它是 .NET 运行时的一种扩展。

不过,很多资深开发者仍习惯称它为 "huatuo",算是一个有趣的社区梗。现在官方文档和代码库中两者都会提到,但正式名称是 HybridCLR。

核心特点

1、支持热更新

允许在运行时加载新的 .dll(如逻辑代码、修复补丁),无需重新打包或发布应用。

适用于 iOS(由于 Apple 禁止 JIT,传统热更方案如 Lua/ILRuntime 性能较低,而 HybridCLR 能提供更好的性能)。

2、基于 IL2CPP,但支持动态性

IL2CPP 原本是 AOT(提前编译),无法动态加载新代码,HybridCLR 扩展了它的能力,使其支持解释执行新代码。

3、高性能

比纯解释型方案(如 ILRuntime、Lua)更快,因为 HybridCLR 能直接运行编译后的 IL 代码,减少转换开销。

4、兼容性高

支持大部分 C# 语法(包括泛型、反射、async/await 等),比部分热更方案(如 ILRuntime)的限制更少。

5、多平台支持

使用HybridCLR技术的游戏不仅能在Android平台,也能在IOS、Consoles、WebGL等所有il2cpp支持的平台上高效运行。

和其他热更新方案的比较

特性

xLua

HybridCLR

ILRuntime

技术

Lua 脚本

IL2CPP + 解释器

纯 C# 解释执行

性能

⭐⭐⭐(LuaJIT 优化后较好)

⭐⭐⭐⭐(接近原生)

⭐⭐(解释执行较慢)

iOS 支持

✅(解释执行允许)

✅(扩展 IL2CPP)

✅(但性能较差)

学习成本

需学 Lua

直接使用 C#

直接使用 C#(但有兼容限制)

适用场景

业务逻辑热更

高性能需求、全平台热更

简单热更,无 iOS 高性能需求

        HybridCLR 是目前 Unity 热更新方案中 性能最好、兼容性最强 的选择之一,特别适合 iOS 平台 或 对性能要求较高的项目。它弥补了 IL2CPP 无法动态加载代码的缺陷,同时避免了 Lua/ILRuntime 的性能问题,是当前热更新技术的重要突破。

快速上手

1、安装HybridCLR

打开Package Manager,点击左上角加号,点击Add package from git URL...,

然后填入

https://gitee.com/focus-creative-games/hybridclr_unity.git

 然后点击Add

打开菜单HybridCLR/Installer..., 点击安装按钮进行安装。 耐心等待30s左右,安装完成后会在最后打印 安装成功日志。

2、创建热更新模块

创建 Assets/HotUpdate 目录

在目录下 右键 Create/Assembly Definition,创建一个名为HotUpdate的程序集模块

3、配置HybridCLR

打开菜单 HybridCLR/Settings, 在Hot Update Assemblies配置项中添加HotUpdate程序集,如下图:

4、配置IL2CPP

参考该博客的 使用IL2CPP目录下的操作步骤

Unity Mono与IL2CPP比较-CSDN博客

5、创建热更测试相关脚本

创建ConsoleToScreen.cs脚本

创建 Assets/ConsoleToScreen.cs 脚本类,这个脚本用于测试,它可以打印日志到屏幕上,方便定位错误。

using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class ConsoleToScreen : MonoBehaviour
{
    const int maxLines = 50;
    const int maxLineLength = 120;
    private string _logStr = "";

    private readonly List<string> _lines = new List<string>();

    public int fontSize = 15;

    void OnEnable() { Application.logMessageReceived += Log; }
    void OnDisable() { Application.logMessageReceived -= Log; }

    public void Log(string logString, string stackTrace, LogType type)
    {
        foreach (var line in logString.Split('\n'))
        {
            if (line.Length <= maxLineLength)
            {
                _lines.Add(line);
                continue;
            }
            var lineCount = line.Length / maxLineLength + 1;
            for (int i = 0; i < lineCount; i++)
            {
                if ((i + 1) * maxLineLength <= line.Length)
                {
                    _lines.Add(line.Substring(i * maxLineLength, maxLineLength));
                }
                else
                {
                    _lines.Add(line.Substring(i * maxLineLength, line.Length - i * maxLineLength));
                }
            }
        }
        if (_lines.Count > maxLines)
        {
            _lines.RemoveRange(0, _lines.Count - maxLines);
        }
        _logStr = string.Join("\n", _lines);
    }

    void OnGUI()
    {
        GUI.matrix = Matrix4x4.TRS(Vector3.zero, Quaternion.identity,
           new Vector3(Screen.width / 1200.0f, Screen.height / 800.0f, 1.0f));
        GUI.Label(new Rect(10, 10, 800, 370), _logStr, new GUIStyle() { fontSize = Math.Max(10, fontSize) });
    }
}


创建主场景

  • 创建默认初始场景 main.scene
  • 场景中创建一个空GameObject,将ConsoleToScreen挂到上面
  • Build Settings中添加main场景到打包场景列表

创建热更新脚本

创建 Assets/HotUpdate/Hello.cs 文件,代码内容如下

using System.Collections;
using UnityEngine;

public class Hello
{
    public static void Run()
    {
        Debug.Log("Hello, HybridCLR");
    }
}

创建Assets/LoadDll.cs脚本,然后在main场景中创建一个GameObject对象,挂载LoadDll脚本

using HybridCLR;
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Threading.Tasks;
using UnityEngine;
using UnityEngine.Networking;

public class LoadDll : MonoBehaviour
{

    void Start()
    {
        // Editor环境下,HotUpdate.dll.bytes已经被自动加载,不需要加载,重复加载反而会出问题。
#if !UNITY_EDITOR
        Assembly hotUpdateAss = Assembly.Load(File.ReadAllBytes($"{Application.streamingAssetsPath}/HotUpdate.dll.bytes"));
#else
        // Editor下无需加载,直接查找获得HotUpdate程序集
        Assembly hotUpdateAss = System.AppDomain.CurrentDomain.GetAssemblies().First(a => a.GetName().Name == "HotUpdate");
#endif
    
        Type type = hotUpdateAss.GetType("Hello");
        type.GetMethod("Run").Invoke(null, null);
    }
}

运行main场景,屏幕上会显示 'Hello,HybridCLR',表示代码工作正常。

6、打包运行

运行菜单 HybridCLR/Generate/All 进行必要的生成操作。这一步不可遗漏!!!

 将{项目根目录}/HybridCLRData/HotUpdateDlls/StandaloneWindows64(MacOS下为StandaloneMacXxx)目录下的HotUpdate.dll复制到Assets/StreamingAssets/HotUpdate.dll.bytes注意,要加.bytes后缀!!!

打开Build Settings对话框,点击Build And Run,打包并且运行热更新示例工程。如果打包成功,并且屏幕上显示 'Hello,HybridCLR',表示热更新代码被顺利执行!

7、测试热更新

修改Assets/HotUpdate/Hello.cs的Run函数中Debug.Log("Hello, HybridCLR");代码,改成Debug.Log("Hello, World");

运行菜单命令HybridCLR/CompileDll/ActiveBulidTarget重新编译热更新代码。

 将{项目根目录}/HybridCLRData/HotUpdateDlls/StandaloneWindows64(MacOS下为StandaloneMacXxx)目录下的HotUpdate.dll复制替换刚才的打包输出目录的 XXX_Data/StreamingAssets/HotUpdate.dll.bytes

重新运行程序,会发现屏幕中显示Hello, World,表示热更新代码生效了

至此完成热更新体验!!!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2396940.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

ElasticSearch迁移至openGauss

Elasticsearch 作为一种高效的全文搜索引擎&#xff0c;广泛应用于实时搜索、日志分析等场景。而 openGauss&#xff0c;作为一款企业级关系型数据库&#xff0c;强调事务处理与数据一致性。那么&#xff0c;当这两者的应用场景和技术架构发生交集时&#xff0c;如何实现它们之…

【C语言极简自学笔记】项目开发——扫雷游戏

一、项目概述 1.项目背景 扫雷是一款经典的益智游戏&#xff0c;由于它简单而富有挑战性的玩法深受人们喜爱。在 C 语言学习过程中&#xff0c;开发扫雷游戏是一个非常合适的实践项目&#xff0c;它能够综合运用 C 语言的多种基础知识&#xff0c;如数组、函数、循环、条件判…

Maven概述,搭建,使用

一.Maven概述 Maven是Apache软件基金会的一个开源项目,是一个有优秀的项目构建(创建)工具,它用来帮助开发者管理项目中的jar,以及jar之间的依赖关系,完成项目的编译,测试,打包和发布等工作. 我在当前学习阶段遇到过的jar文件: MySQL官方提供的JDBC驱动文件,通常命名为mysql-…

Unity 环境搭建

Unity是一款游戏引擎&#xff0c;可用于开发各种类型的游戏和交互式应用程序。它由Unity Technologies开发&#xff0c;并在多个平台上运行&#xff0c;包括Windows、macOS、Linux、iOS、Android和WebGL。Unity也支持虚拟现实(VR)和增强现实(AR)技术&#xff0c;允许用户构建逼…

【入门】【练9.3】 加四密码

| 时间限制&#xff1a;C/C 1000MS&#xff0c;其他语言 2000MS 内存限制&#xff1a;C/C 64MB&#xff0c;其他语言 128MB 难度&#xff1a;中等 分数&#xff1a;100 OI排行榜得分&#xff1a;12(0.1*分数2*难度) 出题人&#xff1a;root | 描述 要将 China…

使用 SASS 与 CSS Grid 实现鼠标悬停动态布局变换效果

最终效果概述 页面为 3x3 的彩色格子网格&#xff1b;当鼠标悬停任意格子&#xff0c;所在的行和列被放大&#xff1b;使用纯 CSS 实现&#xff0c;无需 JavaScript&#xff1b;利用 SASS 的模块能力大幅减少冗余代码。 HTML 结构 我们使用非常基础的结构&#xff0c;9 个 .i…

Spring如何实现组件扫描与@Component注解原理

Spring如何实现组件扫描与Component注解原理 注解配置与包扫描的实现机制一、概述&#xff1a;什么是注解配置与包扫描&#xff1f;二、处理流程概览三、注解定义ComponentScope 四、核心代码结构1. ClassPathScanningCandidateComponentProvider2. ClassPathBeanDefinitionSca…

达梦数据库 Windows 系统安装教程

&#x1f9d1; 博主简介&#xff1a;CSDN博客专家、CSDN平台优质创作者&#xff0c;高级开发工程师&#xff0c;数学专业&#xff0c;10年以上C/C, C#, Java等多种编程语言开发经验&#xff0c;拥有高级工程师证书&#xff1b;擅长C/C、C#等开发语言&#xff0c;熟悉Java常用开…

【Java EE初阶】计算机是如何⼯作的

计算机是如何⼯作的 计算机发展史冯诺依曼体系&#xff08;Von Neumann Architecture&#xff09;CPU指令&#xff08;Instruction&#xff09;CPU 是如何执行指令的&#xff08;重点&#xff09; 操作系统&#xff08;Operating System&#xff09;进程(process) 进程 PCB 中的…

RAG理论基础总结

目录 概念 流程 文档收集和切割 读取文档 转换文档 写入文档 向量转换和存储 搜索请求构建 向量存储工作原理 向量数据库 文档过滤和检索 检索前 检索 检索后 查询增强和关联 QuestionAnswerAdvisor查询增强 高级RAG架构 自纠错 RAG&#xff08;C-RAG&#xf…

列表推导式(Python)

[表达式 for 变量 in 列表] 注意&#xff1a;in后面不仅可以放列表&#xff0c;还可以放range ()可迭代对象 [表达式 for 变量 in 列表 if 条件]

一天搞懂深度学习--李宏毅教程笔记

目录 1. Introduction of Deep Learning1.1. Neural Network - A Set of Function1.2. Learning Target - Define the goodness of a function1.3. Learn! - Pick the best functionLocal minimaBackpropagation 2. Tips for Training Deep Neural Network3. Variant of Neural…

python打卡训练营打卡记录day43

复习日 作业&#xff1a; kaggle找到一个图像数据集&#xff0c;用cnn网络进行训练并且用grad-cam做可视化 进阶&#xff1a;并拆分成多个文件 数据集来源&#xff1a;Flowers Recognition 选择该数据集原因&#xff1a; 中等规模&#xff1a;4242张图片 - 训练快速但足够展示效…

【QT控件】QWidget 常用核心属性介绍 -- 万字详解

目录 一、控件概述 二、QWidget 核心属性 2.1 核心属性概览 2.2 enabled ​编辑 2.3 geometry 2.4 windowTitle 2.5 windowIcon 使用qrc文件管理资源 2.6 windowOpacity 2.7 cursor 2.8 font ​编辑 2.9 toolTip 2.10 focusPolicy 2.11 styleSheet QT专栏&…

uniapp-商城-77-shop(8.2-商品列表,地址信息添加,级联选择器picker)

地址信息,在我们支付订单上有这样一个接口,就是物流方式,一个自提,我们就显示商家地址。一个是外送,就是用户自己填写的地址。 这里先说说用户的地址添加。需要使用到的一些方式方法,主要有关于地址选择器,就是uni-data-picker级联选择。 该文介绍了电商应用中地址信息处…

【第16届蓝桥杯 | 软件赛】CB组省赛第二场

个人主页&#xff1a;Guiat 归属专栏&#xff1a;算法竞赛 文章目录 A. 密密摆放&#xff08;5分填空题&#xff09;B. 脉冲强度之和&#xff08;5分填空题&#xff09;C. 25 之和D. 旗帜E. 数列差分F. 树上寻宝G. 翻转硬币H. 破解信息 正文 总共8道题。 A. 密密摆放&#xff0…

AR/MR实时光照阴影开发教程

一、效果演示 1、PICO4 Ultra MR 发光的球 2、AR实时光照 二、实现原理 PICO4 Ultra MR开发时&#xff0c;通过空间网格能力扫描周围环境&#xff0c;然后将扫描到的环境网格材质替换为一个透明材质并停止扫描&#xff1b;基于Google ARCore XR Plugin和ARFoundation进行安卓手…

【汽车电子入门】一文了解LIN总线

前言&#xff1a;LIN&#xff08;Local Interconnect Network&#xff09;总线&#xff0c;也就是局域互联网的意思&#xff0c;它的出现晚于CAN总线&#xff0c;于20世纪90年代末被摩托罗拉、宝马、奥迪、戴姆勒、大众以及沃尔沃等多家公司联合开发&#xff0c;其目的是提供一…

【笔记】为 Python 项目安装图像处理与科学计算依赖(MINGW64 环境)

&#x1f4dd; 为 Python 项目安装图像处理与科学计算依赖&#xff08;MINGW64 环境&#xff09; &#x1f3af; 安装目的说明 本次安装是为了在 MSYS2 的 MINGW64 工具链环境中&#xff0c;搭建一个完整的 Python 图像处理和科学计算开发环境。 主要目的是支持以下类型的 Pyth…

智能守护电网安全:探秘输电线路测温装置的科技力量

在现代电力网络的庞大版图中&#xff0c;输电线路如同一条条 “电力血管”&#xff0c;日夜不息地输送着能量。然而&#xff0c;随着电网负荷不断增加&#xff0c;长期暴露在户外的线路&#xff0c;其线夹与导线在电流热效应影响下&#xff0c;极易出现温度异常。每年因线路过热…