
ET 框架 HybridCLR 热更新集成包包结构、运行时加载链路与编辑器工具链详解【免费下载链接】ETUnity3D Client And C# Server Framework项目地址: https://gitcode.com/GitHub_Trending/et/ET导读cn.etetet.hybridclr是 ET 框架中集成 HybridCLR 的官方包为 Unity 客户端提供基于 il2cpp 改造的原生 C# 热更新能力。本文以 AGENTS.md 为核心骨架结合仓库源码深入讲解该包的目录约定、运行时加载链路补充元数据装载 → 程序集加载 → 入口启动、运行时 API 配置项以及编辑器生成工具链并给出代码规范et-code与构建验证et-build的使用约定帮助读者理解并正确接入 ET HybridCLR 热更新体系。一、包概览cn.etetet.hybridclr 在 ET 中的定位按照 AGENTS.md 的概述该包是HybridCLR 集成包包含热更新相关的运行时、插件和编辑器工具三大部分。从 package.json 可以看到包的元信息字段值说明namecn.etetet.hybridclr包唯一标识遵循 ET 包命名规范version8.5.1当前仓库集成的 HybridCLR 版本displayNameET.HybridCLRUnity 编辑器中的显示名categoryRuntime归类为运行时包keywordsHybridCLR / hotupdate / hotfix / focus-creative-games / code-philosophy检索关键词HybridCLR 本身是对 il2cpp 运行时的扩充它将纯 AOT预编译runtime 改造成AOT Interpreter混合 runtime从而原生支持动态加载 assembly从底层实现 C# 热更新。ET 通过这个包把 HybridCLR 的运行时Runtime/、原生插件Plugins/、编辑器生成与打包工具Scripts/Editor/以及安装器Editor/Installer等统一收纳为一个可随包分发的 Unity Package。仓库中该包的完整演进记录见 RELEASELOG.md最新条目为 8.5.12025-08-25修复了值类型上System.Activator.CreateInstanceT()的 instinct 变换栈计算缺陷并修复了 PInvokeAnalyzer 对 PInvoke 函数调用约定的计算问题8.4.0 起支持自定义 image 格式8.1.0 用std::unordered_set优化了Assembly.Load的耗时降为原来的约 33%。这些条目也印证了该包是运行时 编辑器双线并进维护的。二、HybridCLR 技术原理从纯 AOT 到 AOT Interpreter 混合运行时理解本包的目录结构与工具链需要先掌握 HybridCLR 的核心原理。根据 README.md 的说明HybridCLR 受 mono 的 mixed mode execution 技术启发为 il2cpp 这类 AOT runtime 额外提供 interpreter 模块使其从纯 AOT 变为AOT Interpreter混合运行方式。具体做了五方面工作实现高效的元数据dll解析库改造元数据管理模块实现元数据的动态注册补充元数据机制实现IL 指令集到自定义寄存器指令集的 compiler即 IL 转换器实现高效的寄存器解释器interpreter 执行引擎提供大量instinct 函数提升解释器性能。从使用者视角看这些机制带来的直接能力包括热更新代码与 AOT 代码无缝协作、支持继承/泛型/反射/多线程volatile、ThreadStatic、async Task 等、支持热更新 MonoBehaviour 与 ScriptableObject、支持MonoPInvokeCallback/PInvoke与原生代码交互、支持 DHE 差分混合执行与热重载等。版本支持方面仓库 README 声明支持 2019.4.x、2020.3.x、2021.3.x、2022.3.x、2023.2.x、6000.x.y 等 LTS 版本以及所有 il2cpp 支持的平台含团结引擎与鸿蒙平台——具体以仓库实际集成的 8.5.1 为准。在 ET 中这套原理最终落到一个关键 APIHybridCLR.RuntimeApi.LoadMetadataForAOTAssembly详见第四节。三、目录约定详解编辑器代码、运行时与原生插件的组织方式AGENTS.md 的「目录约定」是理解本包结构的关键仓库实际目录如下Packages/cn.etetet.hybridclr/ ├── AGENTS.md / README.md / README_EN.md / RELEASELOG.md # 包文档与版本日志 ├── Data~/ # 编辑器工具使用的原生数据.dll/.tpl/.json 等 ├── Editor/ # 原生工具与历史编辑器资源UnityHook/7zip/UnityFS 等 ├── HybridCLR/ │ └── AssemblyReferenceToLoader.asmref # 程序集引用汇入 ET.Loader ├── Plugins/ # dnlib.dll、LZ4.dll 等托管依赖 ├── Runtime/ # 运行时 API 与 ET.HybridCLR.asmdef └── Scripts/ ├── Editor/ # 编辑器 C# 代码Commands/BuildProcessors/Settings 等 └── Model/ # 共享模型如 PackageType.cs3.1Scripts/Editor编辑器代码统一落点按 AGENTS.md 约定编辑器代码放在Scripts/Editor下并通过AssemblyReference.asmref汇入ET.Editor同时明确不再使用包根Editor目录承载编辑器 C# 代码。对照仓库实际布局包根Editor/目录保留的是非 C# 的原生资源与工具如3rds/UnityHook下的Utils.cpp、libMonoHookUtils_OSX.dylib及构建脚本3rds/7zip、3rds/UnityFS等第三方组件而全部编辑器 C# 源码都集中在 Scripts/Editor/Share 目录树中Settings/HybridCLRSettings.cs配置项定义、HybridCLRSettingProvider.csProject Settings 面板、MenuProvider.cs菜单项Commands/PrebuildCommand、CompileDllCommand、StripAOTDllCommand、AOTReferenceGeneratorCommand、LinkGeneratorCommand、MethodBridgeGeneratorCommand、Il2CppDefGeneratorCommandBuildProcessors/CheckSettings、FilterHotFixAssemblies、PatchScriptingAssemblyList、CopyStrippedAOTAssemblies、ScriptingAssembliesJsonPatcher、AddLil2cppSourceCodeToXcodeproj*按 Unity 2019/2020-2021/2022/2023 分版本实现AOT/AOTAssemblyMetadataStripper裁剪 AOT dll、Analyzer、GenericReferenceWriterLink/、MethodBridge/、Il2CppDef/、Meta/、ABI/、Installer/、HotUpdate/MissingMetadataChecker、Template/等模块目录。这种包根只放原生资源、C# 编辑器代码全部收进Scripts/Editor并由 asmref 汇入ET.Editor的组织方式是为了让包内的编辑器代码真正进入 ET 的主编辑器程序集从而能调用 ET.Editor 提供的构建管线与工具函数。3.2HybridCLR/AssemblyReferenceToLoader.asmref运行时汇入 ET.Loader包根下还有一个关键程序集引用文件 AssemblyReferenceToLoader.asmref它把本包的运行时程序集ET.HybridCLR.asmdef汇入ET.Loader。这正是 CodeLoader.cs 中可以直接调用HybridCLR.RuntimeApi.LoadMetadataForAOTAssembly(...)的编译期前提——运行时加载逻辑与 HybridCLR API 在同一程序集内详见第四节。3.3Runtime运行时 API 与程序集定义Runtime 目录包含运行所需的全部 API 文件文件职责ET.HybridCLR.asmdef运行时程序集定义RuntimeApi.cs热更新入口 API补充元数据装载、预编译、运行参数读写RuntimeOptionId.cs解释器运行参数枚举栈大小、方法体缓存、内联深度等HomologousImageMode.cs补充元数据装载模式LoadImageErrorCode.cs装载返回的错误码ReversePInvokeWrapperGenerationAttribute.cs反向 P/Invoke 包装生成标记3.4Plugins托管第三方依赖Plugins 目录提供编辑器阶段的托管依赖dnlib.dll.NET 元数据处理库供Meta/、MethodBridge/、Link/等编辑器模块解析程序集与LZ4.dllLZ4 压缩供3rds/UnityFS处理 AssetBundle 相关格式。四、运行时加载链路CodeLoader 与补充元数据装载AGENTS.md 概述中提到的运行时能力在 ET 中由 CodeLoader.cs 承担具体落地。其Start()方法是热更新加载的完整链路可拆分为四个阶段阶段一下载热更新资源。await DownloadAsync()获取 dll/pdb 等热更资源见 CodeLoader.cs。阶段二装载 AOT 补充元数据核心热更步骤。在非编辑器环境#if !UNITY_EDITOR下遍历this.aotDlls中的每个 TextAsset调用HybridCLR.RuntimeApi.LoadMetadataForAOTAssembly(textAsset.bytes, HybridCLR.HomologousImageMode.SuperSet);见 CodeLoader.cs。这一步的作用是把AOT 程序集的补充元数据动态注册进 il2cpp 元数据系统使热更新代码可以正常使用泛型实例化、反射等需要完整元数据的特性。装载模式使用HomologousImageMode.SuperSet超集模式即补充元数据 dll 为原始 AOT dll 的超集LoadImageErrorCode枚举则定义了装载失败时的错误码如 OK/错误码见 LoadImageErrorCode.cs。阶段三动态加载热更新程序集。依次Assembly.Load(modelAssBytes, modelPdbBytes)加载ET.Model/ET.ModelView并通过LoadHotfix()加载ET.Hotfix/ET.HotfixViewpdb 同时加载以保留栈调试行号信息见 CodeLoader.cs 与 CodeLoader.cs。阶段四装配并启动入口。将加载出的程序集列表交给CodeTypes单例注册类型然后通过反射调用热更新程序集中的ET.Entry.Start启动游戏逻辑见 CodeLoader.cs。需要特别注意的是仓库代码注释提醒编辑器调试时可改用File.ReadAllBytes(Path.Combine(Define.CodeDir, ET.Model.dll.bytes))直接读取本地生成的热更 dll见 CodeLoader.cs但真正打包发布时必须使用下载/内置的热更资源路径。五、运行时 API 与解释器运行参数RuntimeApi.cs 是热更新运行时的主要编程接口按功能分组如下补充元数据装载。LoadMetadataForAOTAssembly(byte[] dllBytes, HomologousImageMode mode)返回LoadImageErrorCode。注意它在编辑器下是空实现return LoadImageErrorCode.OK仅在真机/发布环境通过[MethodImpl(MethodImplOptions.InternalCall)]桥接到 native 层。预编译Prejit。PreJitMethod(MethodInfo method)与PreJitClass(Type type)用于在游戏启动时提前 JIT 解释器方法规避首次调用时的解释开销返回true表示成功预编译false表示无法预编译。编辑器下同样为空实现。运行参数读写。通过GetRuntimeOption(RuntimeOptionId)/SetRuntimeOption(RuntimeOptionId, int)读写解释器参数并封装了如GetInterpreterThreadObjectStackSize()等便捷方法。RuntimeOptionId.cs 定义了全部参数枚举值数值含义InterpreterThreadObjectStackSize1解释器线程对象栈的 StackObject 数量上限实际内存约 size×8 字节InterpreterThreadFrameStackSize2解释器线程帧栈大小ThreadExceptionFlowSize3线程异常流转栈大小MaxMethodBodyCacheSize4方法体缓存上限MaxMethodInlineDepth5方法内联最大深度MaxInlineableMethodBodySize6可内联方法体的最大体积这些参数与 RELEASELOG 中 7.0.0新增方法内联与 7.1.0默认MaxInlineableMethodBodySize由 16 调整为 32的演进一一对应可以在游戏启动早期按项目负载特征调优。反向 P/Invoke。ReversePInvokeWrapperGenerationAttribute用于标记需要生成反向 P/Invoke 包装的委托配合编辑器端MethodBridge生成器支持从 native如 Lua/JS回调热更新 C# 方法。六、编辑器工具链生成命令、打包处理器与配置项6.1 命令菜单Commands编辑器菜单HybridCLR/Generate/*对应 Commands 下的各生成命令典型工作流为PrebuildCommand—— 生成前的预处理如检查 HybridCLR 是否已安装CompileDllCommand—— 把热更新程序集编译为目标平台的 dllStripAOTDllCommand—— 裁剪 AOT 程序集产出补充元数据所需的精简 dll配合AOTAssemblyMetadataStripper去除非泛型函数元数据AOTReferenceGeneratorCommand—— 分析热更新程序集对 AOT 泛型类型/方法的引用生成补充元数据清单AOTGenericReferences.csLinkGeneratorCommand—— 扫描热更新程序集自动生成link.xml防止 AOT 链接裁剪掉运行所需的元数据MethodBridgeGeneratorCommand—— 生成托管/native 双向调用的桥接函数MethodBridgeIl2CppDefGeneratorCommand—— 生成 il2cpp 定义相关代码UnityVersion.h.tpl、AssemblyManifest.cpp.tpl、MethodBridge.cpp.tpl等模板来自Data~目录。6.2 打包处理器BuildProcessorsBuildProcessors 通过 UnityIPreprocessBuildWithReport等回调在打包阶段自动工作CheckSettings校验 Scripting Backend 必须为 il2cpp 及 API 兼容级别FilterHotFixAssemblies从构建中过滤热更程序集PatchScriptingAssemblyList/ScriptingAssembliesJsonPatcher修正scriptingassemblies.json把热更程序集从 AOT 编译列表剔除CopyStrippedAOTAssemblies拷贝裁剪后的 AOT dll 供运行时装载补充元数据AddLil2cppSourceCodeToXcodeproj*负责在 iOS/macOS 导出 Xcode 工程时把 HybridCLR 的 native 源码libil2cpp 扩展注入工程。6.3 配置项HybridCLRSettings编辑器配置定义在 HybridCLRSettings.cs序列化存储于 Unity 工程根目录ProjectSettings/HybridCLRSettings.asset见该文件GetFilePath()实现L71-L74并通过HybridCLRSettingProvider在 Project Settings 面板中展示。核心字段及默认值字段默认值说明enabletrue是否启用 HybridCLRuseGlobalIl2cppfalse是否使用 Unity 安装目录中的全局 il2cpphybridclrRepoURL/il2cppPlusRepoURLgitee 仓库地址安装器拉取 hybridclr / il2cpp_plus 源码的仓库 URLhotUpdateAssemblyDefinitions—热更新程序集的 asmdef 资源列表hotUpdateAssemblies—热更新程序集名列表不带 .dll 后缀preserveHotUpdateAssemblies—需保留的热更新程序集名hotUpdateDllCompileOutputRootDirHybridCLRData/HotUpdateDlls热更 dll 编译输出目录externalHotUpdateAssembliyDirs—外部热更程序集搜索路径strippedAOTDllOutputRootDirHybridCLRData/AssembliesPostIl2CppStrip裁剪后 AOT dll 输出目录patchAOTAssemblies—补充元数据程序集名列表outputLinkFileHybridCLRGenerate/link.xml自动生成的 link.xml 输出路径outputAOTGenericReferenceFileHybridCLRGenerate/AOTGenericReferences.cs自动生成的泛型引用清单输出路径maxGenericReferenceIteration10热更程序集中泛型方法搜索的最大迭代次数maxMethodBridgeGenericIteration10AOT 程序集中方法桥接泛型搜索的最大迭代次数6.4 安装器与体检工具InstallerInstallerWindow/InstallerController/BashUtil提供图形化安装入口负责把 HybridCLR 的 libil2cpp 扩展源码下载并接入 Unity 安装目录HotUpdate/MissingMetadataChecker则用于在开发期检测热更新代码引用了 AOT 泛型但缺少补充元数据等典型配置遗漏避免发布后才暴露运行时错误。七、代码规范与构建验证AGENTS.md 引用的两个 skillAGENTS.md 的「详细文档」部分将本包的开发工作流锚定到 harness 的两个 skill这两者共同构成 HybridCLR 包的维护规范7.1 代码规范/et-codeet-code SKILL.md 覆盖 ET 框架 C# 代码编写与审查流程对本包以及依赖它的热更新模块的约束要点包括新建或修改Entity/Component/System/Helper、消息 Handler、程序集与包依赖时启用纯测试、配置导出或 Unity 编辑器操作场景不加载该 skill改动前先确认代码所在 package、程序集层级和包内AGENTS.md规则判断是否影响 Entity/System 分离、HandlerRun规范、包依赖单向与 Module analyzer涉及async/await/ETTask/EntityRef时叠加 et-async skill默认一类一文件严禁 AI 手工生成.meta或手工修改.csproj移动 C# 文件必须同步移动.meta以保留 GUID——这与本包目录约定中 asmref/asmdef 的组织方式直接相关输出要求说明代码落点、包依赖、程序集层次是否正确是否影响.meta/.csproj/ Unity 刷新或工程文件生成是否引入新的 analyzer 风险、静态状态风险或模块边界问题。7.2 构建验证/et-buildet-build SKILL.md 提供编译、Proto 导出、服务器启动与发布的唯一标准入口编译与分析器验证统一使用dotnet build ET.sln不单独编译包或 IDE 私有方案Proto 导出dotnet ./Bin/ET.Proto2CS.dll启动服务器dotnet ./Bin/ET.App.dll --Console1必须在 Unity 项目根目录启动不在Bin/目录启动运行前先清理旧Logs/发布pwsh -ExecutionPolicy Bypass -File ./Scripts/Publish.ps1特别提醒Model / Hotfix 程序集不能用 IDE 编译必须走项目规定的 Unity / ET 编译入口——这正是 HybridCLR 热更 dll 由编辑器CompileDllCommand生成的原因。八、实践小结与接入注意事项综合以上分析在 ET 项目中接入cn.etetet.hybridclr时应把握以下要点结构认知编辑器 C# 代码统一在 Scripts/Editor通过 asmref 汇入ET.Editor运行时通过 AssemblyReferenceToLoader.asmref 汇入ET.Loader包根Editor/只保留原生工具资源。加载顺序不可颠倒真机加载必须先装载 AOT 补充元数据HomologousImageMode.SuperSet→ 再Assembly.Load热更程序集 → 最后反射调用ET.Entry.Start参见 CodeLoader.cs。配置与生成配套HybridCLRSettings中的热更程序集列表、补充元数据列表、link.xml 与 AOTGenericReferences 输出路径必须与Generate/*命令的执行结果保持一致否则会出现 MissingMetadata / 链接裁剪类问题。发布约束以仓库实际集成的 8.5.1 版本为准关注 RELEASELOG.md 中的关键修复如打包时Texture Compression设置被改动、WebGL 平台scriptingassemblies.json路径等问题升级包后需重新执行安装器并重新生成。开发纪律遵循et-code的代码规范.meta 同步、一类一文件、包依赖单向与et-build的构建入口dotnet build ET.sln、Publish.ps1避免绕过既定管线导致热更链路不一致。【免费下载链接】ETUnity3D Client And C# Server Framework项目地址: https://gitcode.com/GitHub_Trending/et/ET创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考