当前位置: 首页 > news >正文

Unity + HybirdCLR热更新 入门篇

官方文档

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_EDITORAssembly 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");
#endifType 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.xdnf.cn/news/767359.html

相关文章:

  • GStreamer开发笔记(六):gstreamer基本概念:组件、箱柜、管道、衬垫、链接组件
  • 【端午安康】龙舟争渡Plug-In
  • 计算机组成原理核心剖析:CPU、存储、I/O 与总线系统全解
  • 空调清洗教程
  • Python----目标检测(《YOLOv3:AnIncrementalImprovement》和YOLO-V3的原理与网络结构)
  • 20250602在Ubuntu20.04.6下修改压缩包的日期和时间
  • 分布式锁优化:使用Lua脚本保证释放锁的原子性问题
  • SQL进阶之旅 Day 12:分组聚合与HAVING高效应用
  • 微服务-Sentinel
  • Oracle expdp过滤部分表数据
  • vue-12 (路由守卫:全局、每个路由和组件内)
  • 【Unity】相机 Cameras
  • 项目管理进阶:56页大型IT项目管理实践经验分享【附全文阅读】
  • 数据库系统概论(十四)详细讲解SQL中空值的处理
  • Leetcode 2123. 使矩阵中的 1 互不相邻的最小操作数
  • 数据结构之堆:解析与应用
  • 高阶数据结构——并查集
  • vscode 插件 eslint, 检查 js 语法
  • mysql分布式教程
  • 构建高性能风控指标系统
  • AIGC工具平台-GPT-SoVITS-v4-TTS音频推理克隆
  • Arbitrum Stylus 合约实战 :Rust 实现 ERC721
  • Windows 账号管理与安全指南
  • Java后端优化:对象池模式解决高频ObjectMapper实例化问题及性能影响
  • SCAU8639--折半插入排序
  • JS手写代码篇---手写类型判断函数
  • Linux 基础指令入门指南:解锁命令行的实用密码
  • 无他相机:专业摄影,触手可及
  • 【C++高级主题】转换与多个基类
  • 电力系统时间同步系统