官方文檔
什么是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
,表示熱更新代碼生效了
至此完成熱更新體驗!!!