The IL2CPP (Intermediate Language To C++) scripting backendA framework that powers scripting in Unity. Unity supports three different scripting backends depending on target platform: Mono, .NET and IL2CPP. Universal Windows Platform, however, supports only two: .NET and IL2CPP. More info
See in Glossary is an alternative to the Mono backend. IL2CPP provides better support for applications across a wider range of platforms. The IL2CPP backend converts MSIL (Microsoft Intermediate Language) code (for example, C# code in scripts) into C++ code, then uses the C++ code to create a native binary file (for example, .exe, .apk, or .xap) for your chosen platform.
This type of compilation, in which Unity compiles code specifically for a target platform when it builds the native binary, is called ahead-of-time (AOT) compilation. The Mono backend compiles code at runtime, with a technique called just-in-time compilation (JIT).
On this page:
Some platforms don’t support AOT compilationAhead of Time (AOT) compilation is an iOS optimization method for optimizing the size of the built iOS player More info
See in Glossary, so the IL2CPP backend doesn’t work on every platform. Other platforms support AOT and IL2CPP, but don’t allow JIT compilation, and so can’t support the Mono backend. When a platform can support both backends, Mono is the default. For more information, see Scripting restrictions.
IL2CPP can improve performance across a variety of platforms, but the need to include machine code in built applications increases both the build time and the size of the final built application. For more information, see How IL2CPP works and the blog series An introduction to IL2CPP internals.
IL2CPP supports the debugging of managed code in the same way as the Mono scripting backend. For more information, see Debugging C# code in Unity.
To build a project with IL2CPP, you need to have the backend installed in your Unity installation. You can select IL2CPP as an optional module when you first install a version of Unity, or add IL2CPP support to an existing installation through the Unity Hub. For more information, see Installing the Unity Hub and Add modules to the Unity Editor.
IL2CPP also requires some systems native to the target platform to generate the C++ code. This means that to use IL2CPP on a specific platform, you need to build the application on that platform. For example, to use IL2CPP with MacOS as a build target, you need to build the application on a machine that uses MacOS. For more information about system requirements for desktop platforms, including IL2CPP requirements for individual platforms, see the Desktop section of System Requirements for Unity.
You can change the scripting backend Unity uses to build your application in one of two ways:
Through the Player SettingsSettings that let you set various player-specific options for the final game built by Unity. More info
See in Glossary menu in the Editor. Perform the following steps to change the scripting backend through the Player Settings menu:
You can also open the Player Settings menu from inside the Build Settings menu; go to File > Build Settings and click on the Player Settings button.
Through the Editor scripting API. Use the PlayerSettings.SetScriptingBackend property to change the scripting backend that Unity uses.
When you start a build using IL2CPP, Unity automatically performs the following steps:
Both IL2CPP and Mono provide a few useful options which you can control with attributes in your scriptsA piece of code that allows you to create your own Components, trigger game events, modify Component properties over time and respond to user input in any way you like. More info
See in Glossary. For more information, see Platform-dependent compilation.
IL2CPP enables Unity to pre-compile code for specific platforms. The binary file Unity produces at the end of this process already contains necessary machine code for the target platform, while Mono has to compile this machine code at runtime during execution. AOT compilation does increase build time, but it also improves compatibility with the target platform and can improve performance.
Both scripting backends require a new build for each platform you want to target. For example, to support both the Android and iOSApple’s mobile operating system. More info
See in Glossary platforms, you need to build your application twice and produce two binary files.
The assembly stripping stage helps reduce the final binary size. Unity removes any bytecode that the final built application doesn’t use.
Project build times when using IL2CPP can be significantly longer than when using Mono. However, you can do several things to reduce build time.
Exclude your project from anti-malware software scans
You can exclude your Unity project folder and target build folders from anti-malware software scans before you build your project.
Store your project and target build folder on a solid-state drive (SSD)
Solid-state drives (SSDs) have faster read/write speeds than traditional hard disk drives (HDD). Converting IL code to C++ and compiling it involves a large number of read/write operations, so a faster storage device speeds up this process.
When you use the IL2CPP scripting backend, you can control how il2cpp.exe generates C++ code. You can use the Il2CppSetOption attribute to enable or disable the following runtime checks:
Property: | Description: | Default: |
---|---|---|
Null checks | If this option is enabled, the C++ code that IL2CPP generates contains null checks and throws managed NullReferenceException exceptions as necessary. If this option is disabled, IL2CPP doesn’t emit the null checks into the generated C++ code. For some projects, disabling this option might improve runtime performance. When this setting is disabled, Unity doesn’t prevent attempts to access null values in the generated code, which might lead to incorrect behavior. Your application is likely to crash soon after it dereferences the null value. Unity recommends that you don’t disable this option. |
Enabled |
Array bounds checks | If this option is enabled, the C++ code that IL2CPP generates contains array bounds checks and throws managed IndexOutOfRangeException exceptions as necessary. If this option is disabled, IL2CPP doesn’t emit the array bounds checks into the generated C++ code. For some projects, disabling this option might improve runtime performance. However, when this option is disabled, Unity doesn’t prevent attempts to access an array with invalid indices in the generated code, which might lead to incorrect behavior, including reading from or writing to arbitrary memory locations. In most cases, these memory accesses occur without any immediate side effects, and can corrupt the state of the application with no obvious warning signs. This can make debugging these errors extremely difficult. Unity recommends that you keep this option enabled. |
Enabled |
Divide by zero checks | If this option is enabled, C++ code generated by IL2CPP contains divide by zero checks for integer division and throw managed DivideByZeroException exceptions as necessary. If this option is disabled, IL2CPP doesn’t emit the divide by zero checks on integer division into the generated C++ code. These checks have an impact on performance at runtime. You should only enable this option if you need to run divide by zero checks; otherwise, leave it disabled. |
Disabled |
To use the Il2CppSetOption attribute:
The below example describes how to use the Il2CppSetOption attribute:
[Il2CppSetOption(Option.NullChecks, false)]
public static string MethodWithNullChecksDisabled()
{
var tmp = new object();
return tmp.ToString();
}
You can apply Il2CppSetOption attribute to types, methods, and properties. Unity uses the attribute from the most local scope.
[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();
}
}
}
• 2018–05–15 Page amended