Unity のビルドプロセスでは、未使用のマネージコードを削除するために Unity リンカーというツールを使用します。Unity リンカーは IL Linker のバージョンの 1 つで、Unity で動作するようにカスタマイズされています。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 ファイルでも使用することができます。
ストリッピングレベルを High に設定すると、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>
ストリッピングレベルを High に設定すると、Unity リンカーはコードサイズをさらに削減するためにメソッドのボディを編集します。このセクションでは、Unity リンカーがメソッドのボディに対して行う編集の注意すべき点をいくつかまとめています。
Unity リンカーは、.NET クラスライブラリアセンブリのメソッドのボディのみを編集します。メソッドのボディの編集後は、アセンブリのソースコードとアセンブリのコンパイル済みコードが一致しなくなり、デバッグが困難になる場合があります。
以下のリストは、Unity リンカーがメソッド本体を編集するために実行するアクションを説明したものです。