版本:Unity 6 (6000.0)
语言:English
Mono 概述
处理 IL2CPP 附加参数的平台特定设置

IL2CPP 概述

IL2CPP(中间语言到 C++)脚本后端为 Unity 中的脚本编写提供支持的框架。根据目标平台的不同,Unity 支持三种不同的脚本后端:Mono、.NET 和 IL2CPP。但是,通用 Windows 平台仅支持两种:.NET 和 IL2CPP。更多信息
参见 术语表
是 Mono 后端的一种替代方案。IL2CPP 为更广泛的平台上的应用程序提供了更好的支持。IL2CPP 后端将 MSIL(Microsoft 中间语言)代码(例如,脚本中的 C# 代码)转换为 C++ 代码,然后使用 C++ 代码为所选平台创建本地二进制文件(例如,.exe、.apk 或 .xap)。

这种编译类型称为提前(AOT)编译,其中 Unity 在构建本地二进制文件时针对目标平台编译代码。Mono 后端 使用称为即时编译(JIT)的技术在运行时编译代码。

此页面内容

某些平台不支持AOT 编译提前(AOT)编译是除 iOS 外所有平台都使用的优化方法,用于优化构建播放器的尺寸。 更多信息
参见 术语表
,因此 IL2CPP 后端并非在所有平台上都能正常工作。其他平台支持 AOT 和 IL2CPP,但不允许 JIT 编译,因此无法支持 Mono 后端。当平台可以支持两种后端时,Mono 为默认后端。有关更多信息,请参见脚本限制

IL2CPP 可以提高各种平台的性能,但需要在构建的应用程序中包含机器代码,这会增加构建时间和最终构建应用程序的大小。有关更多信息,请参见 IL2CPP 的工作原理以及博文系列IL2CPP 内部机制简介

IL2CPP 支持以与 Mono 脚本后端相同的方式调试托管代码。有关更多信息,请参见在 Unity 中调试 C# 代码

使用 IL2CPP 构建项目

要使用 IL2CPP 构建项目,您需要在 Unity 安装中安装后端。您可以在首次安装 Unity 版本时选择 IL2CPP 作为可选模块,或通过 Unity Hub 将 IL2CPP 支持添加到现有安装中。有关更多信息,请参见安装 Unity Hub向 Unity 编辑器添加模块

IL2CPP 还需要目标平台的一些原生系统才能生成 C++ 代码。这意味着要在一个特定平台上使用 IL2CPP,您需要在该平台上构建应用程序。例如,要将 IL2CPP 与 MacOS 作为构建目标一起使用,您需要在使用 MacOS 的机器上构建应用程序。有关桌面平台系统要求的更多信息,包括各个平台的 IL2CPP 要求,请参见Unity 系统要求中的“桌面”部分。

您可以通过以下两种方式之一更改 Unity 用于构建应用程序的脚本后端

  • 通过编辑器中的**播放器设置**菜单。执行以下步骤以通过**播放器设置**菜单更改脚本后端

    1. 转到**编辑** > **项目设置**。
    2. 点击**播放器设置**按钮以在**检查器**中打开当前平台的**播放器**设置。
    3. 导航到**其他设置**子菜单下的**配置**部分标题。
    4. 点击**脚本后端**下拉菜单,然后选择**IL2CPP**。

    您也可以从**构建配置文件**窗口打开**播放器设置**菜单;转到**文件** > **构建配置文件**,然后点击**播放器设置**选项卡。

  • 通过编辑器脚本 API。使用PlayerSettings.SetScriptingBackend 属性更改 Unity 使用的脚本后端。

The Configuration section of the Player settings
**播放器**设置的**配置**部分

要开始构建过程,请打开**构建配置文件**窗口并点击**构建**按钮。然后,Unity 会将您的 C# 代码和程序集转换为 C++,最后为您的目标平台生成一个二进制文件。

IL2CPP 的工作原理

当您开始使用 IL2CPP 进行构建时,Unity 会自动执行以下步骤

  1. Roslyn C# 编译器会将应用程序的 C# 代码和任何必需的包代码编译为 .NET DLL(托管程序集)。
  2. Unity 应用托管字节码剥离。此步骤可以显著减小构建应用程序的尺寸。
  3. IL2CPP 后端将所有托管程序集转换为标准 C++ 代码。
  4. C++ 编译器使用原生平台编译器编译生成的 C++ 代码和 IL2CPP 的运行时部分。
  5. Unity 创建可执行文件或 DLL,具体取决于您目标的平台。

IL2CPP 和 Mono 都提供了一些有用的选项,您可以使用脚本一段代码,允许您创建自己的组件,触发游戏事件,随时间推移修改组件属性并以您喜欢的任何方式响应用户输入。更多信息
参见 术语表
中的属性来控制这些选项。有关更多信息,请参见平台相关编译

IL2CPP 使 Unity 能够为特定平台预编译代码。Unity 在此过程结束时生成的二进制文件已包含目标平台所需的机器代码,而 Mono 必须在执行期间的运行时编译此机器代码。AOT 编译确实会增加构建时间,但它也会提高与目标平台的兼容性,并可以提高性能。

两种脚本后端都需要为每个要定位的平台进行新的构建。例如,要支持 Android 和 iOS 平台,您需要构建两次应用程序并生成两个二进制文件。

程序集剥离阶段有助于减小最终二进制文件的大小。Unity 会删除最终构建应用程序未使用的所有字节码。

优化 IL2CPP 构建时间

使用 IL2CPP 时,项目构建时间可能比使用 Mono 时长得多。但是,您可以执行以下几件事来缩短构建时间。

将您的项目排除在反恶意软件软件扫描之外

在构建项目之前,您可以将 Unity 项目文件夹和目标构建文件夹排除在反恶意软件软件扫描之外。

将您的项目和目标构建文件夹存储在固态硬盘 (SSD) 上

固态硬盘 (SSD) 的读写速度比传统硬盘驱动器 (HDD) 快。将 IL 代码转换为 C++ 并对其进行编译会涉及大量的读写操作,因此使用更快的存储设备可以加快此过程。

更改播放器设置中的 IL2CPP 代码生成选项

要更改 IL2CPP 生成代码的方式,请打开播放器设置允许您为 Unity 生成的最终游戏设置各种特定于播放器的选项。更多信息
参见 术语表
并配置 IL2CPP 代码生成选项。默认情况下,启用“更快的运行时”选项,这会生成更多机器代码,从而减少 IL2CPP 在运行时的影响。要缩短构建时间,您可以将此选项设置为“更快的(更小)构建”。此方法会在二进制可执行文件中生成和包含较少的机器代码,因此可能会降低运行时的性能,但也会大大缩短构建时间和二进制文件大小。

使用 Il2CppSetOption 启用运行时检查

当您使用 IL2CPP 脚本后端时,您可以控制il2cpp.exe生成 C++ 代码的方式。您可以使用Il2CppSetOption属性启用或禁用以下运行时检查

属性 描述 默认值
空值检查 如果启用此选项,则 IL2CPP 生成的 C++ 代码将包含空值检查,并根据需要抛出托管 NullReferenceException 异常。如果禁用此选项,则 IL2CPP 不会将空值检查发出到生成的 C++ 代码中。

禁用此设置后,Unity 不会阻止尝试访问生成的代码中的空值,这可能会导致行为不正确。您的应用程序很可能在取消引用空值后不久就会崩溃。Unity 建议您不要禁用此选项。
启用
数组边界检查 如果启用此选项,则 IL2CPP 生成的 C++ 代码将包含数组边界检查,并根据需要抛出托管 IndexOutOfRangeException 异常。如果禁用此选项,则 IL2CPP 不会将数组边界检查发出到生成的 C++ 代码中。

对于某些项目,禁用此选项可能会提高运行时性能。但是,禁用此选项后,Unity 不会阻止尝试使用无效索引访问生成的代码中的数组,这可能会导致行为不正确,包括读取或写入任意内存位置。在大多数情况下,这些内存访问不会产生任何直接副作用,并且可能会破坏应用程序的状态而没有任何明显的警告信号。这可能使调试这些错误变得极其困难。Unity 建议您保持此选项启用。
启用
除以零检查 如果启用此选项,则 IL2CPP 生成的 C++ 代码将包含针对整数除法的除以零检查,并根据需要抛出托管 DivideByZeroException 异常。如果禁用此选项,则 IL2CPP 不会将整数除法的除以零检查发出到生成的 C++ 代码中。

这些检查会影响运行时的性能。仅当您需要运行除以零检查时才应启用此选项;否则,请将其保持禁用状态。
禁用

要使用Il2CppSetOption属性

  1. 在安装 Unity 版本的目录中,导航到 Windows 上的Data\il2cpp目录,或 OS X 上的Contents/Frameworks/il2cpp目录。
  2. 查找Il2CppSetOptionAttribute.cs源文件。
  3. 将源文件复制到项目的Assets目录中。

以下示例描述了如何使用Il2CppSetOption 属性。

[Il2CppSetOption(Option.NullChecks, false)]
public static string MethodWithNullChecksDisabled()
{
    var tmp = new object();
    return tmp.ToString();
}

您可以将Il2CppSetOption 属性应用于程序集、类型、方法和属性。Unity 使用来自最局部作用域的属性。

[Il2CppSetOption(Option.NullChecks, false)]
public class TypeWithNullChecksDisabled
{
    public static string AnyMethod()
    {
        // Unity doesn’t perform null checks in this method.
        var tmp = new object();
        return tmp.ToString();
    }

    [Il2CppSetOption(Option.NullChecks, true)]
    public static string MethodWithNullChecksEnabled()
    {
        // Unity performs null checks in this method.
        var tmp = new object();
        return tmp.ToString();
    }
}

public class SomeType
{
    [Il2CppSetOption(Option.NullChecks, false)]
    public string PropertyWithNullChecksDisabled
    {
        get
        {
            // Unity doesn’t perform null checks here.
            var tmp = new object();
            return tmp.ToString();
        }
        set
        {
            // Unity doesn’t perform null checks here.
            value.ToString();
        }
    }

    public string PropertyWithNullChecksDisabledOnGetterOnly
    {
        [Il2CppSetOption(Option.NullChecks, false)]
        get
        {
            // Unity doesn’t perform null checks here.
            var tmp = new object();
            return tmp.ToString();
        }
        set
        {
            // Unity performs null checks here.
            value.ToString();
        }
    }
}

其他资源

Mono 概述
处理 IL2CPP 附加参数的平台特定设置