1. Unity 脚本运行体系概览
Unity 的 C# 脚本执行体系主要依赖两大技术:
- Mono/.NET 虚拟机(传统方案)
- IL2CPP(Unity 自研的 Ahead-Of-Time 编译方案)
不同方案在执行原理、性能和平台支持上存在差异。
1.1 Mono/.NET 虚拟机
-
历史背景
- Mono 是微软 .NET 标准开源实现,用于跨平台 .NET 项目(Windows、Linux、macOS、Android 等)。
- Unity 早期选择 Mono 作为底层运行时,实现编辑器和游戏逻辑的跨平台支持。
-
执行原理
- Unity C# 脚本编译为 IL(Intermediate Language)字节码。
- 在不同平台运行时,由 Mono/.NET 运行时将 IL 字节码 JIT(Just-In-Time)编译 成目标平台的 native 机器码执行。
-
特点
- 跨平台能力强,方便在开发和测试阶段快速迭代。
- 调试方便,支持热重载和直接源码调试。
- 性能相对 IL2CPP 略低,因为运行时需要解释或 JIT 编译。
- 对某些平台(如 iOS)有限制,因为 iOS 禁止 JIT。
1.2 IL2CPP
1.2.1 背景与动机
Unity 推出 IL2CPP 主要原因:
| 原因 | 说明 |
|---|---|
| Mono 版权问题 | Unity 希望减少对 Mono 商业授权和维护的依赖。 |
| 性能优化 | Mono/.NET 运行时 JIT 执行 IL 字节码效率较低。 |
| 平台限制 | iOS 等平台不允许内置 JIT 虚拟机。 |
1.2.2 工作原理
IL2CPP(Intermediate Language To C++)的执行流程如下:
C# 脚本 (.cs)↓ C# 编译器
IL 字节码 (.dll)↓ IL2CPP 工具
生成等效 C++ 源码↓ C++ 编译器(针对目标平台)
生成 native 可执行文件(.exe / .apk / .ipa / Mach-O)↓
运行在目标平台 CPU↑
IL2CPP VM 提供运行时支持:
- 对象管理(GC)
- 异常处理
- 类型信息和反射
- 委托和虚方法调用
-
IL2CPP VM:
- 用 C++ 实现,作为轻量级 runtime,为 IL2CPP 生成的 C++ 代码提供 C# 语义支持(GC、异常、委托、反射等)。
- 不是完整的虚拟机,不做 JIT 或 IL 解释执行,所有 native 代码在打包阶段生成。
1.2.3 优势
| 优势 | 说明 |
|---|---|
| 跨平台可移植 | IL2CPP 生成 C++,可通过 C++ 编译器生成多平台 native。 |
| 性能提升 | 生成 native 机器码,运行效率接近 C++ 原生。 |
| 发布兼容性 | iOS、WebGL 等平台必须使用 IL2CPP。 |
| 安全性 | native 代码难以反编译,保护游戏逻辑。 |
-
发布策略
- Unity 几乎所有正式发布版本都基于 IL2CPP,尤其是移动端和 WebGL 平台。
- Mono 保留在开发和编辑器阶段,用于快速迭代和调试。
2. C# IL 在 Unity 中的作用
-
跨语言互操作
- IL 是 C#、VB.NET、F# 等语言统一的中间语言。
- 不同语言都编译成 IL 后,可在同一运行时(CLR / Mono)上无缝调用。
-
语言特性抽象
- IL 抽象了垃圾回收、委托、异常处理和反射等高级特性。
- Unity 使用 IL + Mono 或 IL2CPP VM 来保证 C# 语义在 native 层正确执行。
-
跨平台统一表示
- IL 与平台无关,方便在不同目标平台通过 Mono 或 IL2CPP 生成 native 代码。
3. Mono 与 IL2CPP 对比总结
| 特性 | Mono/.NET | IL2CPP |
|---|---|---|
| 执行方式 | IL → JIT → native | IL → C++ → native |
| Native 生成时机 | 运行时 | 打包阶段(AOT) |
| 调试效率 | 高(源码可调试、支持热重载) | 低(C++ 代码调试复杂) |
| 性能 | 中等 | 高,接近 C++ 原生 |
| 跨平台能力 | 依赖 Mono runtime | 通过 C++ 编译器生成对应平台 native |
| 平台限制 | iOS 需 AOT | 完全支持 iOS、WebGL 等不允许 JIT 的平台 |
| 发布策略 | 开发阶段使用 | 发布阶段主流使用 |
4. 总结
-
Unity 早期选择 Mono/.NET 作为底层 runtime,是为了 跨平台、统一语言管理和快速迭代。
-
随着平台要求提高,Unity 推出 IL2CPP,将 IL 转为 C++ 并生成 native,实现 性能优化、安全性提升和平台兼容性。
-
IL2CPP VM 用 C++ 实现,为 C++ 代码提供 C# 语义支持,保证 IL 转 native 后逻辑一致。
-
当前 Unity 策略:
- 开发阶段:主要使用 Mono,快速迭代和调试
- 发布阶段:几乎全面采用 IL2CPP,提高性能和平台兼容性