关于 unity-hybridclr
unity-hybridclr 是面向 Unity Editor 的技能模块,用于配置 HybridCLR、编译热更程序集、生成构建产物,并为 YooAsset 暂存 DLL。它面向 Unity 开发者,并通过反射避免在未安装 HybridCLR 时产生程序集依赖。
主要功能
- 01检查安装状态、设置、路径和产物
- 02验证 HybridCLR 配置并提供修复建议
- 03编译热更程序集
- 04运行完整生成流程或单个步骤
- 05为 YooAsset Bundle 暂存 DLL
适用场景
- 01构建前检查项目配置
- 02热更代码变更后编译 DLL
- 03玩家构建前生成所需产物
- 04为 YooAsset 收集器暂存 DLL
MCP 相关
它向 MCP 客户端提供 Unity Editor 技能,用于 HybridCLR 状态查询、配置、验证、编译、生成和产物处理。
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ besty0728/ unity-skills --skill unity-hybridclr安装后在 Claude Code 中输入/unity-hybridclr确认已加载。
详细介绍
**调用本模块中的任何技能前:**如果你打算根据技能名称或描述猜测参数后调用技能,请停下——先阅读此文件(或通过
GET /skills/recommend?includeSchema=true获取其架构)。如果你已从 recommend/schema 获取参数定义,则可直接进行 dryRun。
触发条件
- 配置热更新程序集
- 编译热更新 DLL
- 生成 AOTGenericReferences/link.xml
- 排查 HybridCLR 配置问题
- 将输出接入 YooAsset 构建流程
- 配置热更程序集、编译热更 DLL、生成 AOTGenericReferences/link.xml、排查 HybridCLR 环境、把产物接进 YooAsset 打包链路
Unity HybridCLR 技能
用于 HybridCLR 的编辑器端自动化——面向 IL2CPP 的零成本原生 C# 热更新方案。涵盖设置的增删改查、安装探测、热更新程序集编译、预构建生成流程,以及为 YooAsset 资源包构建暂存产物。
**本模块不会直接引用该程序包。**每次调用都会通过反射解析 HybridCLR.Editor 程序集,因此无论是否安装 HybridCLR,UnitySkills Editor 程序集的编译结果都完全一致——无需设置脚本定义符号,安装后也无需重新编译。
需要:
com.code-philosophy.hybridclr(API 基于 8.12.0)、IL2CPP 脚本后端、Unity 2019.4+(建议使用 2022.3+)。 配套模块:yooasset 用于将编译后的 DLL 作为资源包发布;yooasset-design 用于运行时加载约定;asmdef 用于程序集边界设计。
防护规则
运行模式(v1.9 三档):
- Approval(默认):七个只读技能 —
hybridclr_status、hybridclr_install_status、hybridclr_get_paths、hybridclr_settings_get、hybridclr_validate_setup、hybridclr_get_hotupdate_dlls、hybridclr_aot_generic_refs— 均为SemiAuto,可直接运行。hybridclr_settings_set和hybridclr_copy_hotupdate_dlls为 FullAuto:在MODE_RESTRICTED下运行授权协议。 - 禁止自动运行(NeverInSemi,
RiskLevel="high"):hybridclr_compile_dlls、hybridclr_generate_all、hybridclr_generate_step。只能在 Bypass 模式下或通过用户管理的 Allowlist 条目调用;授权流程会返回MODE_FORBIDDEN。这是有意为之 — 这三个技能都会阻塞 Editor 主线程数分钟。 - 当缺少该包时,除
hybridclr_status外的每个技能都会返回MISSING_PACKAGE错误并附上安装说明。当包存在,但无法解析某个反射成员(版本不匹配)时,技能会返回MISSING_PACKAGE,并指出确切的成员,而不是抛出异常。
不要(常见幻觉):
- 不存在
hybridclr_install/hybridclr_init。安装 il2cpp_plus 会克隆两个 git 仓库并复制整个 Editor il2cpp 树;这是一个耗时数分钟、不可取消的网络操作,因此有意不将其设为技能。请在 Editor 中通过 HybridCLR/Installer... 运行,或使用 unity-cli(参见限制)。hybridclr_install_status只会报告状态。 hybridclr_build_player不在此模块中。构建 Player 应使用build_player(Project 模块)或 unity-cli。HybridCLR 会通过自己的IPreprocessBuildWithReport处理器挂接构建;此模块无需执行其他操作。hybridclr_load_metadata/hybridclr_load_assembly是运行时 API(HybridCLR.RuntimeApi.LoadMetadataForAOTAssembly、System.Reflection.Assembly.Load),应写在游戏代码中,而非 Editor REST 接口中。请自行编写。- 不要在每次重建资源包前调用
hybridclr_generate_all— 请参见下方的工作流部分。这是一个构建 Player 前的步骤,而非每次热更新都要执行的步骤。 - 不要向
hybridclr_copy_hotupdate_dlls传入extension=".dll"。Unity 会将暂存文件视为托管插件,并尝试将其加载到 Editor 域;该技能会拒绝此参数。
路由:
- HybridCLR 设置、安装探测、DLL 编译、生成流水线、暂存构建产物 → 此模块。
- 将暂存的 DLL 打包进资源包、配置收集器、构建报告 → yooasset。
- 运行时热更新加载代码(
YooAssets.LoadAssetAsync→Assembly.Load→RuntimeApi.LoadMetadataForAOTAssembly)→ 使用 yooasset-design 自行编写。 - 确定哪些程序集应归入热更新侧 → asmdef。
- 实际构建 Player →
build_player或 unity-cli。
技能
环境(3)
| 技能 | 用途 | 关键参数 |
|---|---|---|
hybridclr_status | 反射探测 — 唯一一个无需安装该包也能运行的技能。报告安装状态、包版本、enable、脚本后端、热更新与 AOT 补丁程序集列表,以及已生成的构建产物。请先调用此技能。 | (无) |
hybridclr_install_status | 通过 InstallerController 检查 il2cpp_plus 的本地安装状态:libil2cpp 是否已打补丁、已安装版本与包版本、预期的 hybridclr / il2cpp_plus 分支,以及 Unity 兼容性。 | buildTarget? |
hybridclr_get_paths | 解析构建目标的所有输入/输出路径 — HybridCLRData 根目录、本地 il2cpp 目录、热更新 DLL 目录、裁剪后的 AOT 目录、link.xml、AOTGenericReferences.cs。用于将输出接入 YooAsset 收集器。 | buildTarget? |
设置(2)
| 工具 | 用途 | 关键参数 |
|---|---|---|
hybridclr_settings_get | 读取每个 HybridCLRSettings 字段,以及 SettingsUtil 根据 asmdef 资源和原始名称派生的已解析程序集列表(这是流水线实际使用的内容)。 | (无) |
hybridclr_settings_set | 写入设置并保存到 ProjectSettings/HybridCLRSettings.asset。仅更改传入的参数;此 HybridCLR 版本未声明的字段会列在 unsupportedFields 中;完整的先前对象会创建快照,以便工作流撤销。 | enable?、useGlobalIl2cpp?、hotUpdateAssemblies?、hotUpdateAssemblyDefinitions?、preserveHotUpdateAssemblies?、patchAOTAssemblies?、externalHotUpdateAssemblyDirs?、hotUpdateDllCompileOutputRootDir?、strippedAOTDllOutputRootDir?、outputLinkFile?、outputAOTGenericReferenceFile?、maxGenericReferenceIteration?、maxMethodBridgeGenericIteration?、hybridclrRepoURL?、il2cppPlusRepoURL? |
诊断(1)
| 工具 | 用途 | 关键参数 |
|---|---|---|
hybridclr_validate_setup | 预检:检查包是否存在、enable、IL2CPP 后端、libil2cpp 是否已修补且版本匹配、热更新程序集是否已配置且可解析、patchAOTAssemblies 是否已填充、link.xml / AOTGenericReferences.cs 是否存在、热更新 DLL 是否已编译。返回分类后的 errors(阻断性)和 warnings(提示性),每项都附有具体的修复方法。 | buildTarget? |
编译与生成(3)——阻断性、高风险
| 工具 | 用途 | 关键参数 |
|---|---|---|
hybridclr_compile_dlls | CompileDllCommand.CompileDll(target, developmentBuild) — 将热更新程序集编译到 HybridCLRData/HotUpdateDlls/<target>。先前的输出会备份,以便工作流撤销。 | buildTarget?、developmentBuild=false |
hybridclr_generate_all | PrebuildCommand.GenerateAll() — 针对当前构建目标运行完整流水线:compile_dll → il2cpp_def → link_xml → aot_dlls → method_bridge → aot_generic_reference。会重写 Assets/ 下的 C# 文件,因此随后会发生域重载。 | (无) |
hybridclr_generate_step | 运行一个流水线步骤:il2cpp_def、link_xml、aot_dlls、method_bridge、aot_generic_reference、clean_il2cpp_cache。假定热更新 DLL 已编译。 | step、buildTarget? |
构建产物(3)
| 工具 | 用途 | 关键参数 |
|---|---|---|
hybridclr_get_hotupdate_dlls | 列出已编译的 DLL 构建产物及其大小和 UTC 时间戳,并与已配置的程序集列表核对,以显示 missing 和 unexpected 条目。 | buildTarget? |
hybridclr_copy_hotupdate_dlls | 将已编译的 DLL(也可选包含剥离后的 AOT DLL)暂存到 Assets/ 下的目录中,并重命名为可导入的扩展名,以便 YooAsset 收集器打包。目标文件会备份,以便工作流撤销。 | destination、buildTarget?、extension=".bytes"、assemblies?、includeAotAssemblies=false、clearDestination=false |
hybridclr_aot_generic_refs | 读取生成的 AOTGenericReferences.cs — 时间戳、声明的 PatchedAOTAssemblyList,以及与 settings.patchAOTAssemblies 的 inSync 比较结果,并提供 missingFromSettings / extraInSettings 差异。 | includeContent=false |
HybridCLR × YooAsset 工作流
这两个模块分工明确:HybridCLR 生成 DLL,YooAsset 负责打包发布。 中间的暂存步骤是 hybridclr_copy_hotupdate_dlls,它会将 .dll 重命名为 .bytes,让 Unity 将其作为 TextAsset 导入(Assets/ 下的裸 .dll 会被视为托管插件)。
一次性设置(每个项目都需要执行,AOT 侧代码变更后也需要重新执行):
u.call_skill("hybridclr_settings_set",
enable=True,
hotUpdateAssemblyDefinitions=["Assets/HotUpdate/HotUpdate.asmdef"])
u.call_skill("hybridclr_validate_setup") # fix every `errors` entry before continuing
u.call_skill("hybridclr_generate_all") # minutes; domain reload follows
refs = u.call_skill("hybridclr_aot_generic_refs")
u.call_skill("hybridclr_settings_set", patchAOTAssemblies=refs["patchedAOTAssemblyList"])
# then build the player normally (build_player / unity-cli)
热更新迭代流程(每次热更新 C# 代码变更时执行——无需运行 generate_all,也无需重新构建 Player):
# 1. edit hot-update C# (script_* skills) — must live in a hotUpdateAssemblyDefinitions asmdef
# 2. compile
u.call_skill("hybridclr_compile_dlls", buildTarget="Android")
u.call_skill("hybridclr_get_hotupdate_dlls", buildTarget="Android") # verify `missing` is empty
# 3. stage into the YooAsset collector directory
u.call_skill("hybridclr_copy_hotupdate_dlls",
destination="Assets/HotUpdateDlls",
buildTarget="Android",
extension=".bytes",
includeAotAssemblies=True, # ships the stripped AOT metadata DLLs too
clearDestination=True)
# 4. pack (yooasset module) — the collector only needs adding once
u.call_skill("yooasset_add_collector",
packageName="DefaultPackage", groupName="HotUpdateCode",
collectPath="Assets/HotUpdateDlls",
addressRule="AddressByFileName", packRule="PackDirectory")
u.call_skill("yooasset_build_bundles",
packageName="DefaultPackage", buildTarget="Android", packageVersion="auto")
边界所在:运行时加载属于你编写的游戏代码,并非技能。通过 YooAsset 加载 .bytes TextAsset,然后对每个 AOT 元数据 DLL 调用 RuntimeApi.LoadMetadataForAOTAssembly(aotBytes, HomologousImageMode.SuperSet),再调用 Assembly.Load(hotUpdateBytes)。顺序很重要。句柄生命周期规则请参阅 yooasset-design。
何时重新运行 generate_all:仅在 AOT 侧代码变更(即热更新 asmdef 以外的任何代码)、添加或移除热更新程序集,或准备发布新的 Player 构建时。仅能从新热更新代码访问的泛型实例化也需要执行此操作——AOTGenericReferences.cs 记录的就是这些内容。
关键规则(必读)
hybridclr_status是唯一无需安装此包即可使用的技能。 其他所有技能都会返回MISSING_PACKAGE。与 YooAsset 模块不同,这里没有编译定义——检测完全通过反射进行,因此安装后无需重新编译。hybridclr_compile_dlls、hybridclr_generate_all和hybridclr_generate_step会阻塞 Editor 主线程。 UnitySkills 通过单一队列在主线程运行所有技能,因此/health和/jobs也会在此期间卡住。请将客户端超时设置为至少 10 分钟;套接字超时不会取消操作。generate_all和generate_step step="aot_dlls"会在内部运行仅构建脚本的BuildPipeline.BuildPlayer,输出到HybridCLRData/StrippedAOTDllsTempProj/<target>。 当BuildPipeline.isBuildingPlayer为true时,两者都会拒绝启动。此步骤会临时切换EditorUserBuildSettings.buildScriptsOnly和平台的“导出项目”标志,并在finally中恢复——如果 Editor 在步骤执行期间崩溃,这些设置可能会保持更改后的状态。patchAOTAssemblies必须与生成的PatchedAOTAssemblyList一致。 每次生成后都运行hybridclr_aot_generic_refs,并将missingFromSettings复制到hybridclr_settings_set(patchAOTAssemblies=[...])。inSync=false表示泛型实例化会在运行时抛出异常。生成的列表带有.dll后缀,而设置中没有;技能会按名称主体进行比较,因此两种形式都可以传入。- 数组参数会替换原值,不会合并。
hybridclr_settings_set(hotUpdateAssemblies=["A"])会丢弃之前配置的所有名称。请先用hybridclr_settings_get读取,再传入完整的目标数组。 HybridCLRSettings不是 AssetDatabase 资源。 它是通过InternalEditorUtility.SaveToSerializedFileAndForget序列化到ProjectSettings/HybridCLRSettings.asset的ScriptableObject,因此不会出现在asset_*技能中,而且 Unity 的撤销堆栈无法还原此文件——只有工作流快照可以。- 路径字段使用两种不同的基准目录。
outputLinkFile和outputAOTGenericReferenceFile相对于Assets/;hotUpdateDllCompileOutputRootDir和strippedAOTDllOutputRootDir相对于项目目录。hybridclr_get_paths会同时返回原始形式和绝对路径形式。 - 上游字段拼错为
externalHotUpdateAssembliyDirs。 技能参数的拼写正确(externalHotUpdateAssemblyDirs),并会映射到该字段;hybridclr_settings_get会在settings下返回上游拼写。 - 热更新代码必须位于
hotUpdateAssemblyDefinitions中列出的 asmdef 内(或位于hotUpdateAssemblies中列出的名称所对应的程序集内)。 这些程序集之外的代码属于 AOT,无法热更新——修改它需要重新构建 Player。 hybridclr_validate_setup会区分errors和warnings。 错误会阻止所有热更新(未启用 IL2CPP、libil2cpp 未打补丁、没有热更新程序集)。警告表示可能过时(DLL 尚未编译、patchAOTAssemblies为空),在设置初期属于正常情况。
限制
- 没有安装工具。
InstallerController.InstallDefaultHybridCLR()可通过反射访问,但特意未公开:它会通过网络克隆两个 git 仓库,并复制整个编辑器 il2cpp 目录树,既不报告进度,也不支持取消,还会在整个过程中占用主线程队列。请使用 HybridCLR/Installer... 窗口,或在批处理模式下使用 unity-cli。 - 同步执行。 这些操作不是
AsyncJobService任务——HybridCLR 的命令是同步的 Unity 主线程 API,没有可供轮询的步骤边界,因此没有可轮询的jobId。请将它们视为耗时较长的阻塞调用。 - 工作流生成操作的撤销仅为部分恢复。
hybridclr_settings_set可完全恢复。hybridclr_compile_dlls和hybridclr_copy_hotupdate_dlls会使用Library/UnitySkills/HybridCLRBackups/下的文件备份恢复受影响的目录。hybridclr_generate_all和hybridclr_generate_step只恢复 Assets 侧的两个产物(link.xml、AOTGenericReferences.cs)以及热更新 DLL 目录——HybridCLRData/下的中间文件和LocalIl2CppData-*/下生成的 C++ 都可重新生成,因此特意不纳入恢复范围。对于这些内容,请重新运行整个流程,不要依赖撤销。 - 每个标签保留 5 代备份。 对
compile_dlls/copy_hotupdate_dlls执行较早撤销步骤时,恢复效果会降级为“移除新增文件,不恢复原有文件”。Library/不受版本控制,因此清空 Library 后备份不会保留。 - 无法控制构建处理器。 HybridCLR 的
IPreprocessBuildWithReport/IPostprocessBuildWithReport钩子(CheckSettings、CopyStrippedAOTAssemblies、PatchScriptingAssemblyList、Xcode 源码注入器)会在播放器构建期间自动运行,无法通过此模块进行配置。 - 报告版本差异,不猜测。 反射目标以 8.12.0 为基准。如果无法解析某个成员,此工具会返回并指出该成员的
MISSING_PACKAGE,而不是悄然不执行任何操作。 hybridclr_aot_generic_refs解析的是生成的文本,而不是 IL。patchedAOTAssemblyList会直接从PatchedAOTAssemblyList初始化器读取,但genericTypeCount统计的是生成器// {{ AOT generic types块中的注释行数,只是近似值。如果需要原样获取文件,请设置includeContent=true。
unity-cli 备用方案
每个生成入口都是带有 [MenuItem] 注解的公开静态无参方法,因此此模块无法执行的操作都可以通过批处理模式下的 -executeMethod 调用:
| 菜单 | -executeMethod 目标 |
|---|---|
| HybridCLR/Generate/All | HybridCLR.Editor.Commands.PrebuildCommand.GenerateAll |
| HybridCLR/CompileDll/ActiveBuildTarget | HybridCLR.Editor.Commands.CompileDllCommand.CompileDllActiveBuildTarget |
| HybridCLR/Generate/LinkXml | HybridCLR.Editor.Commands.LinkGeneratorCommand.GenerateLinkXml |
| HybridCLR/Generate/Il2CppDef | HybridCLR.Editor.Commands.Il2CppDefGeneratorCommand.GenerateIl2CppDef |
| HybridCLR/Generate/AOTDlls | HybridCLR.Editor.Commands.StripAOTDllCommand.GenerateStripedAOTDlls |
| HybridCLR/Generate/MethodBridgeAndReversePInvokeWrapper | HybridCLR.Editor.Commands.MethodBridgeGeneratorCommand.GenerateMethodBridgeAndReversePInvokeWrapper |
| HybridCLR/Generate/AOTGenericReference | HybridCLR.Editor.Commands.AOTReferenceGeneratorCommand.CompileAndGenerateAOTGenericReference |
以无界面方式运行这些命令可完全避免主线程阻塞问题——请参阅 unity-cli。安装没有无参菜单方法,必须通过 Installer 窗口进行。
反射锚点
每项技能都会针对 HybridCLR.Editor 程序集解析这些内容。已根据 hybridclr_unity 8.12.0 源码验证。
| 技能 | 反射目标 |
|---|---|
hybridclr_status | SettingsUtil.Enable、SettingsUtil.HotUpdateAssemblyNamesExcludePreserved、SettingsUtil.AOTAssemblyNames、Installer.InstallerController |
hybridclr_install_status | Installer.InstallerController — HasInstalledHybridCLR()、PackageVersion、InstalledLibil2cppVersion、MajorVersion、GetCompatibleType()、GetCurrentUnityVersionMinCompatibleVersionStr()、HybridclrLocalVersion、Il2cppPlusLocalVersion、LocalVersionFile |
hybridclr_get_paths | SettingsUtil.{ProjectDir, HybridCLRDataDir, LocalUnityDataDir, LocalIl2CppDir, GeneratedCppDir, HotUpdateDllsRootOutputDir}、GetHotUpdateDllsOutputDirByTarget(BuildTarget)、GetAssembliesPostIl2CppStripDir(BuildTarget) |
hybridclr_settings_get / _set | Settings.HybridCLRSettings.Instance 的公共字段 + HybridCLRSettings.Save();通过 SettingsUtil.HotUpdateAssemblyNames{Exclude,Include}Preserved 和 HotUpdateAssemblyFilesIncludePreserved 解析列表 |
hybridclr_compile_dlls | Commands.CompileDllCommand.CompileDll(BuildTarget, bool) |
hybridclr_generate_all | Commands.PrebuildCommand.GenerateAll() |
hybridclr_generate_step | Commands.Il2CppDefGeneratorCommand.GenerateIl2CppDef()、Commands.LinkGeneratorCommand.GenerateLinkXml(BuildTarget)、Commands.StripAOTDllCommand.GenerateStripedAOTDlls(BuildTarget)、Commands.MethodBridgeGeneratorCommand.GenerateMethodBridgeAndReversePInvokeWrapper(BuildTarget) 和 .CleanIl2CppBuildCache()、Commands.AOTReferenceGeneratorCommand.GenerateAOTGenericReference(BuildTarget) |
hybridclr_get_hotupdate_dlls / _copy_hotupdate_dlls | SettingsUtil.GetHotUpdateDllsOutputDirByTarget、GetAssembliesPostIl2CppStripDir、HotUpdateAssemblyFilesIncludePreserved、AOTAssemblyNames |
hybridclr_aot_generic_refs | HybridCLRSettings.outputAOTGenericReferenceFile;输出格式来自 AOT.GenericReferenceWriter.Write |
请注意,当某个名称同时出现在 hotUpdateAssemblies 和 preserveHotUpdateAssemblies 中时,SettingsUtil.HotUpdateAssemblyNamesIncludePreserved 会抛出异常。这些技能会捕获该异常,并将错误消息写入 resolveErrors / hotUpdateAssemblyResolveError,而不是让调用失败。
版本范围
- 目标版本:
com.code-philosophy.hybridclr8.12.0。上述所有类型名称、成员名称和签名均取自该版本的 Editor 源码。 - 最低 Unity 版本:HybridCLR 本身支持 2019.4.0+ / 2020.3.0+ / 2021.3.0+ / 2022.3.0+ / 2023.2.0+ / 6000.0.0+(6000.3 分支上为 6000.3.0+);
hybridclr_install_status会报告当前运行的编辑器所需的准确最低版本。此 Skill 模块已针对 Unity 2022.3 和 6000.3 验证。 - 仅支持 IL2CPP。 Mono 构建无法使用 HybridCLR;
hybridclr_validate_setup会将此问题报告为阻断错误。 - 较旧或较新的包版本仍可用于成员能够解析的功能;无法解析的成员会按名称报告,不会静默跳过。
准确签名
如需获取权威的参数名称、默认值和返回字段,请查询 GET /skills/schema?category=HybridCLR 或 unity_skills.get_skill_schema()。本文档是路由 / 最佳实践指南,并非签名来源。