mcpField
U
unity-hybridclr

unity-hybridclr

github.com/besty0728开发1.9k50 次安装今天更新
代码仓库

关于 unity-hybridclr

unity-hybridclr 是面向 Unity Editor 的技能模块,用于配置 HybridCLR、编译热更程序集、生成构建产物,并为 YooAsset 暂存 DLL。它面向 Unity 开发者,并通过反射避免在未安装 HybridCLR 时产生程序集依赖。

主要功能

  1. 01检查安装状态、设置、路径和产物
  2. 02验证 HybridCLR 配置并提供修复建议
  3. 03编译热更程序集
  4. 04运行完整生成流程或单个步骤
  5. 05为 YooAsset Bundle 暂存 DLL

适用场景

  1. 01构建前检查项目配置
  2. 02热更代码变更后编译 DLL
  3. 03玩家构建前生成所需产物
  4. 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_dllsCompileDllCommand.CompileDll(target, developmentBuild) — 将热更新程序集编译到 HybridCLRData/HotUpdateDlls/<target>。先前的输出会备份,以便工作流撤销。buildTarget?、developmentBuild=false
hybridclr_generate_allPrebuildCommand.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 记录的就是这些内容。

关键规则(必读)

  1. hybridclr_status 是唯一无需安装此包即可使用的技能。 其他所有技能都会返回 MISSING_PACKAGE。与 YooAsset 模块不同,这里没有编译定义——检测完全通过反射进行,因此安装后无需重新编译。
  2. hybridclr_compile_dlls、hybridclr_generate_all 和 hybridclr_generate_step 会阻塞 Editor 主线程。 UnitySkills 通过单一队列在主线程运行所有技能,因此 /health 和 /jobs 也会在此期间卡住。请将客户端超时设置为至少 10 分钟;套接字超时不会取消操作。
  3. generate_all 和 generate_step step="aot_dlls" 会在内部运行仅构建脚本的 BuildPipeline.BuildPlayer,输出到 HybridCLRData/StrippedAOTDllsTempProj/<target>。 当 BuildPipeline.isBuildingPlayer 为 true 时,两者都会拒绝启动。此步骤会临时切换 EditorUserBuildSettings.buildScriptsOnly 和平台的“导出项目”标志,并在 finally 中恢复——如果 Editor 在步骤执行期间崩溃,这些设置可能会保持更改后的状态。
  4. patchAOTAssemblies 必须与生成的 PatchedAOTAssemblyList 一致。 每次生成后都运行 hybridclr_aot_generic_refs,并将 missingFromSettings 复制到 hybridclr_settings_set(patchAOTAssemblies=[...])。inSync=false 表示泛型实例化会在运行时抛出异常。生成的列表带有 .dll 后缀,而设置中没有;技能会按名称主体进行比较,因此两种形式都可以传入。
  5. 数组参数会替换原值,不会合并。 hybridclr_settings_set(hotUpdateAssemblies=["A"]) 会丢弃之前配置的所有名称。请先用 hybridclr_settings_get 读取,再传入完整的目标数组。
  6. HybridCLRSettings 不是 AssetDatabase 资源。 它是通过 InternalEditorUtility.SaveToSerializedFileAndForget 序列化到 ProjectSettings/HybridCLRSettings.asset 的 ScriptableObject,因此不会出现在 asset_* 技能中,而且 Unity 的撤销堆栈无法还原此文件——只有工作流快照可以。
  7. 路径字段使用两种不同的基准目录。 outputLinkFile 和 outputAOTGenericReferenceFile 相对于 Assets/;hotUpdateDllCompileOutputRootDir 和 strippedAOTDllOutputRootDir 相对于项目目录。hybridclr_get_paths 会同时返回原始形式和绝对路径形式。
  8. 上游字段拼错为 externalHotUpdateAssembliyDirs。 技能参数的拼写正确(externalHotUpdateAssemblyDirs),并会映射到该字段;hybridclr_settings_get 会在 settings 下返回上游拼写。
  9. 热更新代码必须位于 hotUpdateAssemblyDefinitions 中列出的 asmdef 内(或位于 hotUpdateAssemblies 中列出的名称所对应的程序集内)。 这些程序集之外的代码属于 AOT,无法热更新——修改它需要重新构建 Player。
  10. 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/AllHybridCLR.Editor.Commands.PrebuildCommand.GenerateAll
HybridCLR/CompileDll/ActiveBuildTargetHybridCLR.Editor.Commands.CompileDllCommand.CompileDllActiveBuildTarget
HybridCLR/Generate/LinkXmlHybridCLR.Editor.Commands.LinkGeneratorCommand.GenerateLinkXml
HybridCLR/Generate/Il2CppDefHybridCLR.Editor.Commands.Il2CppDefGeneratorCommand.GenerateIl2CppDef
HybridCLR/Generate/AOTDllsHybridCLR.Editor.Commands.StripAOTDllCommand.GenerateStripedAOTDlls
HybridCLR/Generate/MethodBridgeAndReversePInvokeWrapperHybridCLR.Editor.Commands.MethodBridgeGeneratorCommand.GenerateMethodBridgeAndReversePInvokeWrapper
HybridCLR/Generate/AOTGenericReferenceHybridCLR.Editor.Commands.AOTReferenceGeneratorCommand.CompileAndGenerateAOTGenericReference

以无界面方式运行这些命令可完全避免主线程阻塞问题——请参阅 unity-cli。安装没有无参菜单方法,必须通过 Installer 窗口进行。

反射锚点

每项技能都会针对 HybridCLR.Editor 程序集解析这些内容。已根据 hybridclr_unity 8.12.0 源码验证。

技能反射目标
hybridclr_statusSettingsUtil.Enable、SettingsUtil.HotUpdateAssemblyNamesExcludePreserved、SettingsUtil.AOTAssemblyNames、Installer.InstallerController
hybridclr_install_statusInstaller.InstallerController — HasInstalledHybridCLR()、PackageVersion、InstalledLibil2cppVersion、MajorVersion、GetCompatibleType()、GetCurrentUnityVersionMinCompatibleVersionStr()、HybridclrLocalVersion、Il2cppPlusLocalVersion、LocalVersionFile
hybridclr_get_pathsSettingsUtil.{ProjectDir, HybridCLRDataDir, LocalUnityDataDir, LocalIl2CppDir, GeneratedCppDir, HotUpdateDllsRootOutputDir}、GetHotUpdateDllsOutputDirByTarget(BuildTarget)、GetAssembliesPostIl2CppStripDir(BuildTarget)
hybridclr_settings_get / _setSettings.HybridCLRSettings.Instance 的公共字段 + HybridCLRSettings.Save();通过 SettingsUtil.HotUpdateAssemblyNames{Exclude,Include}Preserved 和 HotUpdateAssemblyFilesIncludePreserved 解析列表
hybridclr_compile_dllsCommands.CompileDllCommand.CompileDll(BuildTarget, bool)
hybridclr_generate_allCommands.PrebuildCommand.GenerateAll()
hybridclr_generate_stepCommands.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_dllsSettingsUtil.GetHotUpdateDllsOutputDirByTarget、GetAssembliesPostIl2CppStripDir、HotUpdateAssemblyFilesIncludePreserved、AOTAssemblyNames
hybridclr_aot_generic_refsHybridCLRSettings.outputAOTGenericReferenceFile;输出格式来自 AOT.GenericReferenceWriter.Write

请注意,当某个名称同时出现在 hotUpdateAssemblies 和 preserveHotUpdateAssemblies 中时,SettingsUtil.HotUpdateAssemblyNamesIncludePreserved 会抛出异常。这些技能会捕获该异常,并将错误消息写入 resolveErrors / hotUpdateAssemblyResolveError,而不是让调用失败。

版本范围

  • 目标版本:com.code-philosophy.hybridclr 8.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()。本文档是路由 / 最佳实践指南,并非签名来源。

评论

支持 Markdown