Unity のビルドプロセスでは、マネージコードを削除するために Unity リンカーというツールを使用します。Unity リンカーは IL Linker のバージョンの 1 つで、Unity で動作するようにカスタマイズされています。カスタムの Unity エンジン特有の部分は、公開されていません。
Unity リンカーは、マネージコードストリッピングとエンジンコードストリッピングの一部の処理の両方を担当します。エンジンコードストリッピングの一部の処理は IL2CPP スクリプトバックエンドを通じて利用できる別のプロセスで、使用されていないエンジン コードを削除します。詳しくは、PlayerSettings.StripEngineCode を参照してください。
Unity リンカーは、プロジェクト内のすべてのアセンブリを解析します。最初に、ルートタイプ、メソッド、プロパティ、フィールドなどをマークします。例えば、シーン内のゲームオブジェクトに加える MonoBehaviour からの派生クラスはルートタイプです。
次に、Unity リンカーは、マークしたルートを解析して識別し、これらのルートが依存するマネージコードをマークします。この静的解析が完了すると、マークされていない残りのコードは、アプリケーションコードを通るどの実行パスからも到達できなくなり、Unity リンカーはアセンブリからそれを削除します。
Unity エディターは、Unity プロジェクトのシーンで使用されるタイプを含むアセンブリのリストを作成し、Unity リンカーに渡します。Unity リンカーはそれらのアセンブリ、それらのアセンブリの参照、link.xml ファイルで宣言されたアセンブリ、AlwaysLinkAssembly 属性を持つアセンブリを処理します。大概、これらのカテゴリに該当しないプロジェクト内のアセンブリは Unity リンカーで処理されず、プレイヤービルドには含まれません。
Unity リンカーが処理する各アセンブリに対し、それはアセンブリの分類 (アセンブリにシーンで使用される型が含まれているかどうか) と、ビルド用に選択した Managed Stripping Level に基づいた一群の規則に従います。
これらの規則の目的のために、アセンブリは以下のように分類されます。
Unity でプロジェクトをビルドすると、ビルドプロセスは C# コードを共通中間言語 (Common Intermediate Language、CIL) と呼ばれる .NET バイトコード形式にコンパイルします。Unity は、この CIL バイトコードをアセンブリと呼ばれるファイルに梱包します。プロジェクトで使用するプラグインの .NET Framework ライブラリと C# ライブラリも、CIL バイトコードのアセンブリとして事前にパッケージ化されます。
Unity リンカーが静的解析を行うとき、CIL バイトコードのどの部分をビルドに必要なものとしてマークするかは、決定するための規則に従います。ルートのマーキング規則は、Unity リンカーがビルドで最高位のアセンブリをどのように識別して保存するかを決定します。依存関係のマーキングの規則は、ルートアセンブリが依存するコードを Unity リンカーが識別し、保存する方法を決定します。
Managed Stripping Level プロパティは、Unity リンカーが使用する一群の規則を変更します。以下のセクションでは、Managed Stripping Level プロパティで可能な各設定のマークの規則について説明します。
次の表は、Unity リンカーがアセンブリの最高位のタイプを識別する方法を説明したものです。
アセンブリタイプ | マーキングの規則 | ||||
---|---|---|---|---|---|
最低限 | 低 | 中 | 高 | ||
.NET クラス & Platform SDK と UnityEngine アセンブリ | 予防的保存と任意の link.xml ファイルで定義された保存を適用します。 | 予防的保存と任意の link.xml ファイルで定義された保存を適用します。 | link.xml ファイルで定義された保存を適用します。 | link.xml ファイルで定義された保存を適用します。 | |
シーンで参照される型を持つアセンブリ | アセンブリ内のすべての型とメンバーをマークします。 | アセンブリ内のすべての型とメンバーをマークします。 | 以下をマークします。 • [RuntimeInitializeOnLoadMethod] または [Preserve] 属性を持つすべてのメソッド。•link.xml ファイルで定義される保存。 •プリコンパイル、パッケージ、Unity スクリプト、またはアセンブリ定義アセンブリの MonoBehaviour と ScriptableObject から派生したすべての型。 |
以下をマークします。 • [RuntimeInitializeOnLoadMethod] または [Preserve] 属性を持つすべてのメソッド。•link.xml ファイルで定義される保存。 •プリコンパイル、パッケージ、Unity スクリプト、またはアセンブリ定義アセンブリの MonoBehaviour と ScriptableObject から派生したすべての型。 |
|
その他すべて | アセンブリ内のすべての型とメンバーをマークします。 | 以下をマークします。 •これらの型のすべての public 型と public メンバー。 • [RuntimeInitializeOnLoadMethod] または [Preserve] 属性を持つすべてのメソッド。•link.xml ファイルで定義される保存。 •プリコンパイル、パッケージ、Unity スクリプト、またはアセンブリ定義アセンブリの MonoBehaviour と ScriptableObject から派生したすべての型。 |
以下をマークします。 •これらの型のすべての public 型と public メンバー。 • [RuntimeInitializeOnLoadMethod] または [Preserve] 属性を持つすべてのメソッド。•link.xml ファイルで定義される保存。 •プリコンパイル、パッケージ、Unity スクリプト、またはアセンブリ定義アセンブリの MonoBehaviour と ScriptableObject から派生したすべての型。 |
以下をマークします。 • [RuntimeInitializeOnLoadMethod] または [Preserve] 属性を持つすべてのメソッド。•link.xml ファイルで定義される保存。 •プリコンパイル、パッケージ、Unity スクリプト、またはアセンブリ定義アセンブリの MonoBehaviour と ScriptableObject から派生したすべての型。 |
|
テスト |
[UnityTest] 属性を持つメソッド、および NUnit.Framework で定義された属性のアノテーションを持つすべてのメソッドをマークします。 |
Unity リンカーは、アセンブリのルートを特定した後、それらのルートが依存するコードを特定する必要があります。以下の表は、Unity リンカーがアセンブリ内のルート型の依存関係を識別する方法を説明します。
規則のターゲット | 各ストリッピングレベルでの動作 | ||||
---|---|---|---|---|---|
最低限 | 低 | 中 | 高 | ||
MonoBehaviour | Unity リンカーは、型をマークするときに MonoBehavior 型のすべてのメンバをマークします。 | ||||
ScriptableObject | Unity リンカーは、型をマークするときに ScriptableObject 型のすべてのメンバをマークします。 | ||||
属性 | Unity リンカーがアセンブリ、型、またはその他のコードの構造体をマークするときに、それらの構造体のすべての属性もマークします。 | Unity リンカーがアセンブリ、型、またはその他のコードの構造体をマークするときに、それらの構造体のすべての属性もマークします。 | Unity リンカーがアセンブリ、型、またはその他のコード構造をマークするとき、その属性の型もマークされている場合にのみこれらの構造体の属性もマークします。 | Unity リンカーがアセンブリ、型、またはその他のコード構造をマークするとき、その属性の型もマークされている場合にのみこれらの構造体の属性もマークします。 | |
デバッグ用属性 | スクリプトのデバッグが有効な場合、Unity リンカーは、たとえ、メンバーを使用するコードパスがない場合にも[DebuggerDisplay] 属性を持つすべてのメンバーをマークします。 |
スクリプトのデバッグが有効な場合、Unity リンカーは、たとえ、メンバーを使用するコードパスがない場合にも[DebuggerDisplay] 属性を持つすべてのメンバーをマークします。 |
Unity リンカーは常に、DebuggerDisplayAttribute や DebuggerTypeProxyAttribute などのデバッグ属性を削除します。 | Unity リンカーは常に、DebuggerDisplayAttribute や DebuggerTypeProxyAttribute などのデバッグ属性を削除します。 | |
.NET ファサードクラスライブラリ | ランタイムに必要ないため、ファサードアセンブリは削除されます。 |
Link.xml ファイルは、一般的に使用されていない “features” XML 属性をサポートしています。この例では、mscorlib.dll に埋め込まれた mscorlib.xml ファイルがこの属性を使用していますが、適切であれば、どの link.xml ファイルでも使用することができます。
高 レベルのストリッピングでは、Unity リンカーは、現在のビルドの設定に基づいて、サポートされていない機能の保持を除外します。
例えば、以下の link.xml ファイルは、COM をサポートするプラットフォーム上で FeatureOne メソッドを保持し、すべてのプラットフォームで FeatureTwo メソッドを保持します。
<linker>
<assembly fullname="Foo">
<type fullname="Type1">
<!--Preserve FeatureOne on platforms that support COM-->
<method signature="System.Void FeatureOne()" feature="com"/>
<!--Preserve FeatureTwo on all platforms-->
<method signature="System.Void FeatureTwo()"/>
</type>
</assembly>
</linker>
高 ストリッピングレベルを設定すると、Unity リンカーはコードサイズをさらに削減するためにメソッドのボディを編集します。このセクションでは、Unity リンカーがメソッドのボディに対して行う注意すべき編集をまとめています。
Unity リンカーは、.NET クラスライブラリアセンブリのメソッドの本体のみを編集します。メソッド本体編集後は、アセンブリのソースコードとアセンブリ内のコンパイル済みコードが一致しなくなり、デバッグが困難になる場合があります。
以下のリストは、Unity リンカーがメソッド本体を編集するために実行するアクションを説明したものです。