项目初始化
前言
本文是实战系列第二篇(第 43 篇),接续第 42 篇「环境搭建」的成果。在前一篇文章中,我们完成了 HybridCLR 运行环境的搭建,并验证了基础功能正常运行。现在,我们将迈出实践的第一步——从零开始设计项目结构、配置 HybridCLR、编写并执行第一个热更新方法。
前置条件:已完成第 42 篇的全部环境搭建步骤,HybridCLR 在 Unity Editor 中正常工作,能够通过菜单访问 HybridCLR 相关功能。如果尚未完成环境搭建,请先阅读第 42 篇完成准备工作,否则后续操作无法正常进行。
目标:完成项目结构规划,编写第一个热更新代码,成功编译为 DLL 并在运行时加载执行,实现从零到 "Hello Hotfix" 的完整流程。通过本文的实践,读者将掌握 HybridCLR 项目开发的基本工作流,为后续深入热更新业务逻辑打好基础。
一、项目结构设计
在开始编写代码之前,合理的项目结构是保证开发效率的关键。对于 HybridCLR 项目,我们需要将 AOT 主工程代码与热更新代码严格分离,确保热更新代码在编译时不会静态链接到主程序集中。
推荐目录结构
Assets/
├── Scripts/ # AOT 主程序代码
│ ├── Main/
│ ├── Utils/
│ └── HotfixLoader.cs # 热更新 DLL 加载器
├── HotUpdate/ # 热更新代码(将被导出为 DLL)
│ ├── HotUpdate.asmdef # 程序集定义
│ └── Scripts/
│ ├── GameEntry.cs
│ └── Logic/
├── HybridCLRConfig/ # HybridCLR 配置
└── StreamingAssets/ # 热更新资源
└── HotUpdateDlls/ # 导出的 DLL 存放
各目录职责说明
Scripts/ 目录存放 AOT 主工程代码。这部分代码将通过 IL2CPP 静态编译到最终的应用包中,是应用的"骨架"。所有不参与热更新的代码都应放在这里,包括启动流程、底层框架、第三方 SDK 封装等。其中 HotfixLoader.cs 是连接 AOT 与热更新的桥梁,负责在运行时加载并激活热更新 DLL。
HotUpdate/ 目录存放热更新代码。这是 HybridCLR 体系的核心目录,所有需要支持热更的业务逻辑代码都编写在此目录中。该目录下的代码会被编译为独立的 .NET Standard 2.0 DLL,在运行时通过 HybridCLR 的解释器执行。注意,这个目录下的代码不能直接引用 AOT 主工程的代码,但可以通过接口或抽象类间接调用。这种"面向接口编程"的方式是热更新架构的核心设计原则。
HybridCLRConfig/ 目录是 HybridCLR 的配置文件存放位置。包括 AOTGenericTypes.txt、ReflectionTypes.txt、AOTMetaTypes.txt 等配置文件,用于指导 HybridCLR 的代码生成和元数据加载。
StreamingAssets/HotUpdateDlls/ 目录存放编译后的热更新 DLL 文件。这些文件会随应用包一起发布,运行时从 StreamingAssets 加载。建议在此目录中再按版本号建立子目录,便于版本管理和回滚。
程序集定义的重要性
在 Unity 项目中,程序集定义用于将代码组织为独立的程序集。在 HybridCLR 项目中,为热更新代码创建独立的 .asmdef 文件是至关重要的一步——它能确保热更新代码在编译时被隔离,不会意外地链接到主程序集中。如果不设置正确的平台排除规则,热更新代码会被 IL2CPP 编译到 AOT 包中,从而失去热更新能力。
代码示例 1:HotUpdate.asmdef 文件配置
{
"name": "HotUpdate",
"rootNamespace": "HotUpdate",
"references": [],
"includePlatforms": [],
"excludePlatforms": ["Android", "iOS", "Windows", "macOS", "Linux"],
"allowUnsafeCode": false,
"overrideReferences": false,
"precompiledReferences": [],
"autoReferenced": false,
"defineConstraints": [],
"versionDefines": [],
"noEngineReferences": false
}
关键配置说明:
excludePlatforms:排除所有 AOT 平台(Android、iOS、Windows、macOS、Linux),确保此程序集不会被 IL2CPP 静态编译autoReferenced:关闭自动引用,避免 Unity 自动添加程序集引用,保持热更新程序集的纯净references:保持为空,热更新代码不应直接引用 AOT 程序集,改为通过接口桥接overrideReferences:保持关闭,让 Unity 自动管理热更新程序集的引用关系
在配置完 .asmdef 后,需要在 Unity Editor 中点击 Apply 按钮使其生效。此时 HotUpdate 目录下的代码将被编入独立的 HotUpdate.dll 程序集,与主工程 Assembly-CSharp.dll 完全隔离。如果后续在 HotUpdate 目录中添加了新代码,无需修改 .asmdef 配置。这种隔离设计还有另一个好处:热更新代码的修改不会触发主工程代码的重新编译,在大型项目中可以显著缩短迭代周期,将每次修改后的等待时间从几十秒减少到几秒。
资源目录组织
| 目录 | 内容 | 构建方式 |
|---|---|---|
| Assets/Scripts/ | 主工程 C# 代码 | IL2CPP AOT |
| Assets/HotUpdate/ | 热更新 C# 代码 | .NET Standard DLL |
| Assets/HotUpdate/Resources/ | 热更新用到的资源 | AssetBundle |
| Assets/HybridCLRConfig/ | HybridCLR 配置文件 | 配置文件 |
| StreamingAssets/HotUpdateDlls/ | 编译后的热更新 DLL | StreamingAssets |
实际项目中还可能需要更多目录,例如 Addressables 资源管理系统相关的配置目录、第三方 SDK 封装目录等。但上述结构已经构成了 HybridCLR 项目的最小可行骨架,后续文章将在此基础之上逐步扩展。建议在实际项目中严格按照此目录结构组织代码,避免将热更新代码与 AOT 代码混放在同一目录下,否则可能导致编译时意外引用、运行时类型冲突等问题。
二、HybridCLR 基础配置
在完成项目结构设计后,我们需要对 HybridCLR 进行配置,使其能够正确处理热更新代码中的各种类型操作。主要的配置文件有三个:AOTGenericTypes.txt、ReflectionTypes.txt 和 AOTMetaTypes.txt。这三个文件协同工作,确保热更新代码在解释执行时能够正确引用和操作 AOT 层定义的类型与方法。
AOT 泛型配置
AOTGenericTypes.txt 文件用于列出所有在热更新代码中使用的泛型类型实例化。为什么需要这个文件?IL2CPP 在 AOT 编译阶段会实例化所有在 AOT 代码中使用的泛型类型,但对于热更新代码中使用的泛型组合,IL2CPP 在编译时无法预知,因此需要手动列出。
配置格式示例:
System.Collections.Generic.List`1<System.Int32>
System.Collections.Generic.Dictionary`2<System.String, System.Object>
System.Collections.Generic.HashSet`1<System.Int64>
System.Nullable`1<UnityEngine.Vector3>
System.Action`1<System.String>
配置格式为:类型全名 + 反引号 + 泛型参数数量 + <泛型参数列表>。泛型参数需要使用完整的 .NET 类型名称,包括命名空间。特别注意值类型作为泛型参数时(如 List<int>),IL2CPP 会为每个不同的值类型参数生成特化版本,因此必须逐一列出,不能省略。
常见的需要注册的泛型组合包括:
List<T>、Dictionary<TKey, TValue>、HashSet<T>等集合类型Nullable<T>可空值类型Action<T>、Func<T, TResult>等委托类型- 自定义泛型类在热更新中的具体实例化
如果项目中使用了第三方序列化库(如 Newtonsoft.Json),还需要注册其内部使用的泛型实例化。此外,Linq 查询中使用的匿名类型也会触发泛型实例化,例如 .Select(x => x.Name) 可能生成 Func<TSource, TResult> 的实例化,这些都需要在配置文件中覆盖到。
在实际开发中,建议采用以下策略管理 AOTGenericTypes.txt:初始阶段先列出已知的泛型组合,运行测试时观察 HybridCLR 日志中的缺失泛型警告,逐步补全配置。这种迭代式的配置方式比一次性猜测所有泛型组合更为高效。
反射用法配置
ReflectionTypes.txt 文件用于注册热更新代码中通过反射访问的类型。HybridCLR 在解释执行时,某些反射操作(如 typeof()、Type.GetType()、Activator.CreateInstance()、MethodInfo.Invoke() 等)需要提前知道目标类型的元数据。
配置格式示例:
UnityEngine.GameObject
UnityEngine.Transform
UnityEngine.Component
MyGame.PlayerData
MyGame.PlayerController
以下场景都需要注册反射类型:
- 使用
typeof()获取类型 - 使用
Type.GetType("...")按名称加载类型 - 使用
Activator.CreateInstance()动态创建实例 - 使用
SerializeField属性序列化的自定义类型 - 通过 Odin、Newtonsoft.Json 等序列化库处理的类型
- 使用
nameof()获取名称的类型(实际运行时可能触发反射)
元数据配置
AOTMetaTypes.txt 文件记录热更新代码中直接引用的 AOT 类型,这些类型的元数据需要在运行时通过 HybridCLR.RuntimeApi.LoadMetadataForAOTAssembly 加载。幸运的是,HybridCLR 的 Generate 工具会自动分析热更新 DLL 的依赖,生成此文件,通常不需要手动编辑。Generate 工具会遍历热更新 DLL 中所有 IL 指令,提取所有引用的外部 AOT 类型,自动生成完整的元数据依赖清单。
需要注意的是,AOTMetaTypes.txt 中列出的每个程序集都需要在运行时调用一次 LoadMetadataForAOTAssembly。如果某个程序集缺失加载调用,对应的 AOT 类型在热更新代码中将无法正常使用,可能抛出 TypeLoadException 或 MissingFieldException。因此,建议在加载元数据时遍历 AOTMetaTypes.txt 中列出的所有程序集,确保无一遗漏。从工程实践角度看,常见的缺失包括 mscorlib(核心基础类型)、System(泛型集合类型)、System.Core(Linq 相关类型)以及 UnityEngine.CoreModule(Unity 引擎核心类型),务必确认这几项已包含在加载列表中。
一键生成
完成上述配置文件后,通过 HybridCLR 的 Generate 功能可以一次性生成所有必要的补充代码和元数据:
- Unity 菜单路径:HybridCLR > Generate
- 或通过命令行:
unity -batchmode -executeMethod HybridCLR.Editor.Commands.GenerateAll
Generate 命令会自动执行以下操作:
- 读取 AOTGenericTypes.txt,生成 AOT 泛型补充代码
- 读取 ReflectionTypes.txt,收集反射所需的类型信息
- 分析热更新 DLL 的元数据依赖,生成 AOTMetaTypes.txt
- 将生成产物输出到指定目录
代码示例 2:在 C# 代码中加载元数据
using HybridCLR;
using System.Collections.Generic;
using UnityEngine;
public class MetadataLoader
{
public static void LoadAOTMetadata()
{
List<string> aotDllNames = new List<string>
{
"mscorlib",
"System",
"System.Core"
};
foreach (var dllName in aotDllNames)
{
var dllPath = $"{Application.streamingAssetsPath}/HotUpdateDlls/{dllName}.dll";
var dllBytes = System.IO.File.ReadAllBytes(dllPath);
var err = RuntimeApi.LoadMetadataForAOTAssembly(
dllBytes, HomologousImageMode.SuperSet);
Debug.Log($"加载 AOT 元数据 [{dllName}] 结果: {err}");
}
}
}
注意:HomologousImageMode.SuperSet 是推荐的加载模式,表示允许加载的元数据包含比 AOT 镜像更多的类型,完全适用于热更新场景。也可以使用 HomologousImageMode.Consistent 模式,但要求元数据与 AOT 镜像完全一致,在热更新场景下通常没有必要。
配置与生成对照表
| 配置文件 | 生成产物 | 作用 |
|---|---|---|
| AOTGenericTypes.txt | Assembly-CSharp.dll 泛型补充代码 | 补充 AOT 期间未能实例化的泛型组合 |
| ReflectionTypes.txt | AOT 程序集元数据注册表 | 注册反射操作所需的类型元数据 |
| 自动分析(Generate) | HotUpdate.dll 元数据依赖清单 | 运行时加载 AOT 元数据的依据 |
三、第一个热更新方法
完成了项目结构设计和 HybridCLR 配置之后,我们终于可以编写第一个热更新方法了。按照惯例,先从 "Hello Hotfix" 级别的简单方法开始,验证从 AOT 到热更新的完整调用链路能够正常工作。这是后续所有复杂热更新逻辑的基础。
编写热更新代码
在 HotUpdate/Scripts/ 目录下创建 HotfixEntry.cs 文件,编写以下代码:
代码示例 3:第一个热更新入口
using UnityEngine;
namespace HotUpdate
{
public class HotfixEntry
{
public static void Run()
{
Debug.Log("=== 第一个热更新方法执行成功 ===");
Debug.Log($"当前运行平台: {Application.platform}");
Debug.Log($"HybridCLR 运行时版本: {HybridCLR.RuntimeApi.Version}");
var calculator = new Calculator();
int result = calculator.Add(100, 200);
Debug.Log($"计算结果验证: 100 + 200 = {result}");
}
}
public class Calculator
{
public int Add(int a, int b)
{
return a + b;
}
}
}
这段代码包含两个类:HotfixEntry 是热更新入口,Calculator 是一个简单的计算器类。Calculator.Add 方法虽然现在只是简单的加法运算,但未来在热修复场景中,我们可以通过替换 DLL 来修改这个方法的具体实现逻辑,而无需重新发布应用。这正是热更新的核心价值。
编译热更新 DLL
编写完代码后,需要将热更新代码编译为 DLL。通过 HybridCLR 菜单可以完成编译:
HybridCLR > CompileDll > HotUpdate
这会调用 HybridCLR 的编译工具链,将 HotUpdate 目录下的代码编译为 .NET Standard 2.0 格式的 DLL 文件。编译产物输出到 Assets/StreamingAssets/HotUpdateDlls/HotUpdate.dll。
如果在打包脚本中需要自动化编译,可以通过 BuildProcessor 钩子在打包前自动调用:
// 在打包脚本中自动编译热更新 DLL
HybridCLR.Editor.Commands.CompileDllCommand.CompileDll("HotUpdate");
编写加载器代码
在 AOT 主工程中创建一个加载器 HotfixLoader.cs,负责在运行时加载并执行热更新代码。这个文件是整个 AOT 与热更新之间的桥梁:
// Assets/Scripts/HotfixLoader.cs
using System;
using System.IO;
using System.Reflection;
using UnityEngine;
using HybridCLR;
public class HotfixLoader : MonoBehaviour
{
void Start()
{
// Step 1: 加载 AOT 补充元数据
// 这是整个流程的第一步,必须在加载热更新 DLL 之前完成
LoadMetadataForAOTAssemblies();
// Step 2: 加载热更新 DLL
// 从 StreamingAssets 读取 DLL 字节流,通过 RuntimeApi 注册到运行时
byte[] dllBytes = File.ReadAllBytes(
Path.Combine(Application.streamingAssetsPath,
"HotUpdateDlls", "HotUpdate.dll"));
Assembly hotUpdateAss = RuntimeApi.LoadAssembly(dllBytes);
Debug.Log($"热更新 DLL 加载成功,程序集: {hotUpdateAss.FullName}");
// Step 3: 通过反射调用热更新入口方法
Type entryType = hotUpdateAss.GetType("HotUpdate.HotfixEntry");
var runMethod = entryType.GetMethod("Run", BindingFlags.Static | BindingFlags.Public);
runMethod.Invoke(null, null);
}
private void LoadMetadataForAOTAssemblies()
{
// 逐一加载 AOT 补充元数据
string[] aotDlls = { "mscorlib", "System", "System.Core",
"UnityEngine.CoreModule" };
foreach (var dllName in aotDlls)
{
var path = Path.Combine(Application.streamingAssetsPath,
"HotUpdateDlls", $"{dllName}.dll");
var bytes = File.ReadAllBytes(path);
var err = RuntimeApi.LoadMetadataForAOTAssembly(bytes,
HomologousImageMode.SuperSet);
Debug.Log($"加载 AOT 元数据 [{dllName}] 结果: {err}");
}
}
}
注意:这里通过 Type.GetType("HotUpdate.HotfixEntry, HotUpdate") 加载类型,其中第二个参数 "HotUpdate" 是程序集名称(即我们在 .asmdef 中定义的 "name": "HotUpdate")。如果名称不匹配,反射将无法找到目标类型,会返回 null 并导致后续调用失败。因此务必确保类型全名和程序集名称与编译产物完全一致。
完整调用流程
从应用启动到热更新方法执行完成,完整的调用流程如下:
- Unity 启动,IL2CPP 运行时加载主程序集(AOT 代码)
HotfixLoader.Start()被 Unity 生命周期回调MetadataLoader.LoadAOTMetadata()加载 AOT 补充元数据RuntimeApi.LoadAssembly()加载HotUpdate.dll热更新 DLLType.GetType()通过反射获取HotfixEntry类型MethodInfo.Invoke()调用HotfixEntry.Run()静态方法Run()内部代码进入 HybridCLR 解释执行模式Calculator.Add()同样在解释模式下逐条执行 IL 指令Debug.Log()输出执行结果
这个流程揭示了 HybridCLR 的核心工作方式:AOT 代码按传统的 IL2CPP 方式运行,热更新代码则通过解释器逐条执行 IL 指令。两种代码在同一个运行时中高效并存,通过反射机制桥接调用。理解这一调用链路对于后续排查热更新相关问题至关重要——如果某一步失败,可以根据日志精确定位问题所在的阶段。
为了验证调用流程是否成功,可以在 Unity Editor 中运行场景,观察 Console 窗口是否依次输出关键日志。如果全部输出正常,说明整个流程已经跑通,第一个热更新方法成功执行。如果某个日志缺失,根据缺失位置可以快速定位问题:元数据加载失败则检查 AOT 元数据配置,DLL 加载失败则检查编译产物路径,方法调用失败则检查类型名和方法签名。
常见问题排查
| 问题现象 | 可能原因 | 解决方案 |
|---|---|---|
| Assembly.Load 失败 | DLL 路径错误或文件缺失 | 检查 StreamingAssets 路径拼写,确认 Generate 已执行 |
| Method not found 异常 | 方法名或签名不匹配 | 使用 nameof 确保参数正确,检查 GetMethod 参数 |
| TypeLoadException | 类型依赖的 AOT 元数据未加载 | 检查 LoadMetadataForAOTAssembly 调用及加载结果 |
| MissingMethodException | 泛型方法或类型未注册 | 补充 AOTGenericTypes.txt 后重新 Generate |
| ExecutionEngineException | 热更新代码调用了不支持的操作 | 查阅 HybridCLR 兼容性列表,调整代码实现 |
| 热更新代码修改后未生效 | 编辑器缓存了旧版 DLL | 重新编译热更新 DLL 并刷新 StreamingAssets 目录,必要时重启 Unity Editor |
四、调试配置
热更新代码的调试是开发过程中的重要环节。由于热更新代码在解释器中执行,传统的 IL2CPP 调试方式可能无法直接奏效。HybridCLR 为此提供了一系列调试支持功能。
生成调试符号
HybridCLR 支持在编译热更新 DLL 时生成调试符号文件(PDB)。在 HybridCLR 设置中启用 Debug 模式后,编译产出的 DLL 会附带 PDB 符号文件,包含源码行号和局部变量信息,使得 IDE 调试器能够将 IL 指令映射回源代码的具体位置。这对于排查热更新代码中的逻辑错误和异常至关重要——没有符号文件时,调试器只能显示 IL 偏移量,无法定位到对应的 C# 源代码行。
启用方法:HybridCLR Settings > Enable Debug Symbols 或通过脚本:
HybridCLR.Editor.Settings.EnableDebugSymbols = true;
生成的 PDB 文件位于与 DLL 相同的输出目录,需要随 DLL 一起部署到 StreamingAssets/HotUpdateDlls/ 目录。注意发布到生产环境时建议关闭调试符号,以避免泄露源码信息。
配置 IDE 调试器
以 Visual Studio 或 Rider 为例,调试热更新代码的步骤如下。配置一次后,后续的热更新调试体验与传统 AOT 代码调试几乎一致:
- 附加到 Unity 进程:在 IDE 中选择 "Attach to Unity Process",选中当前运行的 Unity Editor 实例
- 设置符号路径:在 IDE 的调试设置中,添加
StreamingAssets/HotUpdateDlls/目录为 PDB 符号文件搜索路径 - 设置断点:在热更新代码的源文件中设置断点,例如
HotfixEntry.Run()的Debug.Log代码行 - 触发执行:在 Unity 中运行场景,
HotfixLoader.Start()执行后,调试器应在断点处暂停
需要注意的是,断点可能在单步执行时出现跳转,这是因为解释器模式下 IL 指令到源码行的映射存在一定偏差,属于正常现象。建议在关键逻辑处使用 Debug.Log 辅以条件编译控制输出级别,作为断点调试的补充手段。
条件编译调试输出
HybridCLR 提供了一个调试宏 HYBRIDCLR_DEBUG,可以在热更新代码中使用条件编译来控制调试日志的输出,避免在发布版本中产生额外的性能开销:
代码示例 5:条件编译调试辅助类
using UnityEngine;
public static class HotfixDebug
{
[System.Diagnostics.Conditional("HYBRIDCLR_DEBUG")]
public static void Log(string message)
{
Debug.Log($"[HotfixDebug] {message}");
}
}
使用方法:在热更新代码中调用 HotfixDebug.Log("当前状态检查"),当 HYBRIDCLR_DEBUG 宏定义时输出日志,未定义时调用被编译器移除,零性能开销。
日志分析
HybridCLR 在运行时会输出诊断日志,通过分析这些日志可以判断热更新运行状态:
[HybridCLR] Initialize. version: x.x.x—— HybridCLR 运行时初始化成功[HybridCLR] load metadata success. dll: mscorlib—— 对应 AOT 元数据加载成功[HybridCLR] assembly HotUpdate loaded—— 热更新程序集加载成功[HybridCLR] method HotUpdate.HotfixEntry::Run is interpreted—— 方法确认进入解释执行模式
如果缺少上述任一日志,说明对应的步骤可能失败。其中元数据加载阶段是最常见的问题源头,应重点检查。例如,如果未出现 load metadata success 日志,说明 LoadMetadataForAOTAssembly 调用可能传入了错误的 DLL 字节数据或使用了不兼容的加载模式,需要逐一排查调用参数。如果程序集加载成功但方法调用失败,则需要检查类型名和方法名的拼写是否正确,以及是否遗漏了必要的程序集引用。
调试常见问题
| 问题 | 原因 | 解决方法 |
|---|---|---|
| 断点无法命中 | PDB 与 DLL 不匹配或符号路径错误 | 重新编译并复制新的 PDB 文件到正确目录 |
| 调试器附加后崩溃 | 解释器调试支持未启用 | 检查 HybridCLR Settings 中的 Debug 模式开关 |
| 变量值显示异常 | IL2CPP 优化导致变量映射偏差 | 关闭 IL2CPP 代码优化(Scripting Optimization 设为 Conservative)后重试 |
| 热更代码抛异常后堆栈不完整 | 解释器堆栈与原生堆栈分离 | 查看 HybridCLR Internal Log 获取完整错误信息 |
| 调试器无法附加到 Unity 进程 | 编辑器或平台调试功能未开启 | 确保 Unity 中开启 Script Debugging,且 Development Build 选项已勾选 |
总结
本文是 HybridCLR 实战系列的实践开篇。我们从项目结构设计入手,规划了 AOT 主工程代码与热更新代码的目录布局,并配置了独立的程序集定义确保编译隔离;然后详细配置了 HybridCLR 的三个核心配置文件(AOTGenericTypes.txt、ReflectionTypes.txt、AOTMetaTypes.txt),确保泛型实例化、反射操作和元数据加载的正确性;接着编写了第一个热更新方法和配套的 DLL 加载器,通过反射桥接完成了从 AOT 到热更新的首次调用,验证了完整的调用流程;最后介绍了调试符号生成、IDE 调试器配置和日志分析方法。
回顾整个闭环:项目结构设计 → HybridCLR 配置 → 编写热更新代码 → 编译 DLL → 加载执行 → 调试验证。至此,我们已经完成了从零到第一个热更新方法执行的全流程闭环,为后续更复杂的业务逻辑热更新奠定了坚实的基础。读者现在应该能够独立搭建一个 HybridCLR 项目骨架,理解各配置文件的用途,并能够编写、编译和加载执行自己的热更新代码。本章节的后续文章将在此基础上逐步完善热更新的完整工作流。
下一篇文章(第 44 篇「热更新流程」)将深入热更新的完整生命周期,涵盖版本管理、资源下载、DLL 热替换、异常回滚等生产级话题,敬请期待。
参考资源
[1] HybridCLR 官方文档:https://hybridclr.doc.code-philosophy.com/
[2] HybridCLR 配置指南 - AOT 泛型:https://hybridclr.doc.code-philosophy.com/docs/basic/aot-generic
[3] HybridCLR 配置指南 - 反射用法:https://hybridclr.doc.code-philosophy.com/docs/basic/reflection
[4] HybridCLR Unity Package - GitHub:GitHub - focus-creative-games/hybridclr_unity: Unity package for HybridCLR · GitHub
[5] Unity 程序集定义(Assembly Definitions)官方文档:Unity - Manual: Organizing scripts into assemblies
[6] 第 42 篇 - 环境搭建:本文的基础前置文章,详细介绍了 HybridCLR 的安装流程与基础验证方法
[7] 第 44 篇 - 热更新流程:本文的后续文章,深入热更新的完整生命周期与生产级部署方案
[8] HybridCLR RuntimeAPI 参考:涵盖 LoadAssembly、LoadMetadataForAOTAssembly、HomologousImageMode 等核心接口的详细说明
[9] IL2CPP 与 Mono 对比分析:理解 AOT 预编译与解释执行差异的参考资料
161万+

被折叠的 条评论
为什么被折叠?



