2025-03-26 00:02:56 +08:00

5.9 KiB
Raw Permalink Blame History

#unity/日常积累

‌在 Unity 中,AOTAhead-of-Time编译是一种将 C# 代码在运行时之前编译为机器代码的技术。AOT 编译通常与 IL2CPPIntermediate Language to C++)相关联,是 Unity 中的一种编译模式,尤其在 iOS 和其他一些平台上使用。

AOT 编译的主要目的是提高性能和缩短启动时间。通过将 C# 代码在应用构建时预先编译成本地代码Unity 可以避免在运行时进行 JITJust-In-Time编译进而提高游戏或应用的性能和稳定性。

AOT 编译的基本概念:

  • IL2CPPIL2CPP 是 Unity 提供的一种技术,它将 C# 程序的中间语言ILIntermediate Language转换为 C++,然后再通过 C++ 编译器编译为平台特定的本地代码。IL2CPP 是 Unity 中 AOT 编译的核心技术。
  • JIT 编译:与 AOT 编译相反JIT 编译是在应用程序运行时,将中间语言代码动态编译为机器代码。这种方式通常会增加启动时间,并消耗更多的系统资源。

使用 AOT 编译的优点:

  1. 性能提升

    • AOT 编译生成的本地代码在运行时执行得更快,因为不需要执行中间代码的编译。
    • 对于内存有限的设备如移动设备AOT 编译有助于减少运行时的内存使用。
  2. 提高稳定性

    • AOT 编译能有效避免由于 JIT 编译引发的运行时错误(如 JIT 编译器的不稳定性)。
    • 对于 iOS 和一些控制严格的平台(如 WiiU、PlayStation 等Apple 和其他平台厂商要求应用使用 AOT 编译以确保安全性和稳定性。
  3. 减少启动时间

    • 由于在构建时就已经完成了编译过程,应用程序的启动时间通常较短,因为它不需要在第一次运行时编译代码。
  4. 适应更多平台

    • 一些平台(如 iOS不允许使用 JIT 编译,而必须使用 AOT 编译,这使得 AOT 编译成为支持这些平台的必需选项。

Unity 中启用 AOT 编译:

Unity 默认在某些平台(如 iOS上使用 AOT 编译。例如,在 iOS 构建时Unity 会强制使用 IL2CPP 并生成 AOT 代码。对于其他平台AOT 编译通常用于 IL2CPP 后端,而使用 Mono 后端的项目则依赖于 JIT 编译。

1. iOS AOT 编译

iOS 平台是最常见的 AOT 编译使用场景,因为 iOS 不允许使用 JIT 编译。在 iOS 构建中Unity 会使用 IL2CPP 进行 AOT 编译。构建过程中Unity 会将 C# 代码转换为 C++,然后再编译为适合 iOS 的本地代码。

设置 iOS AOT 编译:

  • 在 Unity 中,选择 File > Build Settings,然后选择 iOS
  • Player Settings 中,确保设置为使用 IL2CPP 作为脚本后端:
    • Scripting Backend 设置为 IL2CPP
    • Architecture 设置为 ARM64(苹果设备要求使用 64 位架构)。

2. 安卓 AOT 编译

对于 Android 平台Unity 允许选择使用 AOT 编译IL2CPP或者 JIT 编译Mono。默认情况下使用 Mono 时是 JIT 编译,使用 IL2CPP 时会启用 AOT 编译。

设置 Android AOT 编译:

  • Player Settings 中,将 Scripting Backend 设置为 IL2CPP
  • 如果希望启用 AOT可以选择优化选项来缩减最终构建大小或增强性能。

3. 其他平台

在一些支持 IL2CPP 的平台(如 WebGL、Windows、Linux 和 macOSUnity 也可以选择使用 AOT 编译。你可以通过选择 IL2CPP 作为 Scripting Backend 来启用 AOT 编译。

如何优化 AOT 编译:

  1. 预生成 AOT 代码

    • 在 Unity 中,你可以使用 AOT 编译时生成的代码来优化构建的大小和运行时性能。你可以通过为 AOT 编译添加 AOT 预编译,优化代码的生成。
  2. 去除未使用的代码

    • 使用 Managed Stripping LevelLinking 设置来剔除未使用的代码。这样可以减小 AOT 编译后的代码体积。
  3. 合理利用程序集

    • 将项目分成多个程序集,并优化每个程序集的 AOT 编译部分。只编译你需要的代码和资源,减少不必要的构建时间。

AOT 编译与 IL2CPP

  • IL2CPPIntermediate Language to C++)是 Unity 推出的 C# 到 C++ 的编译后端。它通过将中间语言C#)编译成 C++ 代码,再编译为平台特定的二进制代码,从而避免了 JIT 编译。
  • 由于 AOT 编译的执行模式不同IL2CPP 生成的二进制文件通常比传统的 Mono 编译文件大,但它也提供了更好的性能和跨平台支持,尤其在 iOS 等平台上是必需的。

AOT 编译中的限制:

  1. 不支持反射

    • AOT 编译限制了反射的使用,因为反射通常在运行时动态解析类型,这与 AOT 编译的预编译模式不兼容。
    • Unity 提供了 AOT 编译时的反射解决方案,可以通过 Link.xml 文件来告诉 Unity 保留特定类型或成员,避免因 AOT 编译导致的运行时错误。
  2. 代码大小

    • AOT 编译的代码通常比 JIT 编译的代码要大,这可能导致构建文件的体积增大。
    • 你需要确保通过优化和去除未使用的代码来减小最终构建的大小。
  3. 构建时间

    • AOT 编译可能会导致较长的构建时间,尤其是在大型项目中,因为所有代码都需要提前编译为本地代码。

总结:

AOT 编译是 Unity 中提升应用性能和稳定性的关键技术之一,尤其适用于需要严格性能和安全要求的平台(如 iOS。它通过将 C# 代码预先编译成本地机器代码,避免了运行时的 JIT 编译能够显著提高运行时性能并减少启动时间。Unity 支持通过 IL2CPP 后端来进行 AOT 编译,而不同平台的 AOT 编译设置略有不同,需要根据平台需求进行配置和优化。