IL2CPP (Intermediate Language To C++) スクリプティングバックエンドは、Mono バックエンドの代替品です。IL2CPP は、広範なプラットフォームのアプリケーションに対し、優れたサポートを提供します。IL2CPP バックエンドは、MSIL (Microsoft Intermediate Language) コード (スクリプト内の C# コードなど) を C++ コードに変換し、その C++ コードを使って選択したプラットフォーム用のネイティブのバイナリファイル (.exe、.apk、.xap など) を作成します。
このように、Unity がネイティブバイナリをビルドする際に、ターゲットプラットフォームに合わせてコードをコンパイルすることを、事前 (AOT、Ahead-of-Time) コンパイルと呼びます。一方、Mono のバックエンドは、実行時 (JIT) コンパイルと呼ばれる手法で、コードをランタイムにコンパイルします。詳細は、Mono の概要 を参照してください。
このページには以下の情報が含まれています。
AOT コンパイルをサポートしないプラットフォームもあります。そのため、IL2CPP バックエンドはすべてのプラットフォームで動作するわけではありません。また、AOT と IL2CPP をサポートしても、JIT コンパイルができないため、Mono バックエンドをサポートできないプラットフォームもあります。プラットフォームが両方のバックエンドをサポートする場合は、Mono がデフォルトとなります。詳細については、スクリプトの制限 を参照してください。
IL2CPP は、さまざまなプラットフォームのパフォーマンスを向上させることができますが、ビルドされたアプリケーションにマシンコードを置く必要があるため、ビルド時間と最終的にビルドされたアプリケーションのサイズの両方が増加します。詳細については、IL2CPP の仕組みとブログシリーズ An introduction to IL2CPP internals を参照してください。
IL2CPP は、Mono スクリプトバックエンドと同じ方法でマネージドコードのデバッグをサポートします。詳細は、Unity での C# コードのデバッグ を参照してください。
IL2CPP を使ってプロジェクトをビルドするには、Unity のインストール時にバックエンドがインストールされる必要があります。Unity を最初にインストールするときに、必須でないモジュールとして IL2CPP を選択するか、Unity Hub を通じて既存のインストールに IL2CPP のサポートを加えることができます。詳細については、Unity Hub のインストール および Unity エディターへのモジュールの追加 を参照してください。
Unity がアプリケーションのビルドに使用するスクリプティングバックエンドを変更するには、次の 2 つの方法があります。
エディターの Player Settings メニューから。以下の手順で、Player Settings メニューからスクリプティングバックエンドを変更します。
Player Settings メニューは、Build Settings メニューの中からも開くことができます。 File > Build Settings と移動し、Player Settings ボタンをクリックしてください。
エディターのスクリプト API を通じて。PlayerSettings.SetScriptingBackend プロパティを使用して、Unity が使用するスクリプティングバックエンドを変更します。
IL2CPP を使用してビルドを開始すると、Unity は自動的に以下の手順を実行します。
IL2CPP と Mono 両方とも、スクリプトの属性で制御できる便利なオプションをいくつか提供します。詳細は、プラットフォーム依存コンパイル を参照してください。
IL2CPP は、Unity が特定のプラットフォーム用にコードを事前にコンパイルすることを可能にします。このプロセスの最後に Unity が生成するバイナリファイルには、ターゲットプラットフォームに必要なマシンコードがすでに含まれていますが、Mono はこのマシンコードをランタイムにコンパイルしなければなりません。AOT コンパイルは、ビルド時間を増加させますが、ターゲットプラットフォームとの互換性を高め、パフォーマンスを向上させることができます。
どちらのスクリプティングバックエンドも、ターゲットとするプラットフォームごとに新規にビルドする必要があります。例えば、Android と iOS の両方のプラットフォームをサポートするためには、アプリケーションを 2 回ビルドし、2 つのバイナリファイルを作成する必要があります。
アセンブリストリッピングステージでは、最終的なバイナリサイズを小さくすることができます。Unity は、最終的にビルドされるアプリケーションが使用しないバイトコードを削除します。
IL2CPP を使用するプロジェクトのビルド時間は、Mono を使用する場合よりも大幅に長くなることがあります。しかし、ビルド時間を短縮するためにいくつか工夫できます。
マルウェア対策ソフトのスキャンからプロジェクトを除外する
プロジェクトをビルドする前に、Unity のプロジェクトフォルダーとターゲットのビルドフォルダーをマルウェア対策ソフトのスキャン対象から除外します。
プロジェクトとターゲットビルドフォルダーをソリッドステートドライブ (SSD) に保存する
Solid State Drive (SSD) は以前からあるハードディスクドライブ (HDD) に比べ、より速く読み込み、書き込みを行えます。IL コードを C++ に変換しそれをコンパイルすることは、大量の読み込み、書き込み操作を伴います。ストレージデバイスのスピードが速いと、この処理もより早くなります。
IL2CPP スクリプティングバックエンドを使用すると、il2cpp.exe が C++ コードを生成する方法を制御できます。Il2CppSetOptions 属性を使用して、以下のランタイムチェックを有効または無効にすることができます。
プロパティ | 説明 | デフォルト |
---|---|---|
Null checks | このオプションを有効にすると、IL2CPP が生成する C++ コードにはに null チェックが加えられ、必要に応じてマネージ NullReferenceException 例外が投げられます。このオプションを無効にすると、生成された C++ コードに null チェックを加えません。 この設定を無効にすると、Unity が生成されたコードの null 値にアクセスしようとするのを防げないため、誤った動作の原因になる可能性があります。Unity では、このオプションを無効にしないことを推奨します。 |
有効 |
Array bounds checks | このオプションを有効にすると、IL2CPP が生成する C++ コードには配列の境界チェックが加えられ、必要に応じてマネージ IndexOutOfRangeException 例外がスローされます。このオプションを無効にすると、IL2CPP は生成される C++ コードに配列の境界チェックを生成しません。 プロジェクトによっては、このオプションを無効にすることでランタイムパフォーマンスが向上する場合があります。ただし、このオプションを無効にすると、生成されたコード内で無効なインデックスを持つ配列にアクセスしようとする試みが阻止されないため、任意のメモリ位置からの読み取りまたは任意のメモリへの書き込みなど、不正な動作が発生する可能性があります。ほとんどの場合、このようなメモリアクセスは直ちに悪影響を生じることなく発生し、明らかな警告がないままアプリケーションの状態を破壊することがあります。このため、これらのエラーのデバッグは非常に困難になります。Unityでは、このオプションを有効にしておくことを推奨します。 |
有効 |
Divide by zero checks | このオプションを有効にすると、IL2CPP によって生成される C++ コードには、整数のゼロ除算チェックが加えられ、必要に応じて管理された DivideByZeroException 例外を投げます。このオプションを無効にすると、IL2CPP は生成される C++ コードに整数のゼロ除算チェックを加えません。 これらのチェックは、実行時のパフォーマンスに影響を与えます。このオプションは、ゼロ除算チェックを実行する必要がある場合にのみ有効にし、そうでない場合は無効のままにしてください。 |
無効 |
Il2CppSetOptions 属性を使用する手順は以下の通りです。
以下の例では、Il2CppSetOption 属性の使い方を説明します。
[Il2CppSetOption(Option.NullChecks, false)]
public static string MethodWithNullChecksDisabled()
{
var tmp = new object();
return tmp.ToString();
}
Il2CppSetOptions 属性を型、メソッド、プロパティに適用できます。Unity はもっともローカルなスコープから属性を使用します。
[Il2CppSetOption(Option.NullChecks, false)]
public class TypeWithNullChecksDisabled
{
public static string AnyMethod()
{
// このメソッドでは、Unity は null チェックを行いません
var tmp = new object();
return tmp.ToString();
}
[Il2CppSetOption(Option.NullChecks, true)]
public static string MethodWithNullChecksEnabled()
{
// このメソッドでは、Unity は null チェックを行います
var tmp = new object();
return tmp.ToString();
}
}
public class SomeType
{
[Il2CppSetOption(Option.NullChecks, false)]
public string PropertyWithNullChecksDisabled
{
get
{
// ここでは、Unity は null チェックを行いません
var tmp = new object();
return tmp.ToString();
}
set
{
// ここでは、Unity は null チェックを行いません
value.ToString();
}
}
public string PropertyWithNullChecksDisabledOnGetterOnly
{
[Il2CppSetOption(Option.NullChecks, false)]
get
{
// ここでは、Unity は null チェックを行いません
var tmp = new object();
return tmp.ToString();
}
set
{
// ここでは、Unity は null チェックを行います
value.ToString();
}
}
}
•2018–05–15 修正されたページ