Assembly Definition (アセンブリ定義) と Assembly Reference (アセンブリ参照) は、スクリプトをアセンブリにまとめるために作成するアセットです。
アセンブリとは C# のコードライブラリで、スクリプトによって定義されたコンパイル済みのクラスや構造体を含み、他のアセンブリへの参照も定義します。C# のアセンブリに関する一般的な情報は、Assemblies in .NET を参照してください。
デフォルトでは、Unity はほとんどすべてのゲームスクリプトを、定義済みの アセンブリ、Assembly-CSharp.dll にコンパイルします。(Unity は、いくつかのより小さな、特殊な定義済みのアセンブリ も作成します。)
この方法は小規模なプロジェクトには適していますが、プロジェクトにさらに多くのコードを追加すると、いくつかの欠点があります。
アセンブリを定義することで、コードを整理してモジュール性や再利用性を高めることができます。プロジェクトで定義したアセンブリ内のスクリプトは、デフォルトのアセンブリには加えられず、指定した他のアセンブリのスクリプトにアクセスのみを行います。
上の図は、プロジェクトのコードを複数のアセンブリに分割する方法を示しています。Main は Stuff を参照しており、その逆ではないため、Main のコードを変更しても Stuff のコードには影響しません。同様に、Library は他のアセンブリに依存していないので、Library のコードを別のプロジェクトでより簡単に再利用することができます。
ここでは、Assembly Definition と Assembly Definition Reference アセットの作成と設定してプロジェクトのアセンブリを定義する方法について説明します。
関連項目
プロジェクトのコードをアセンブリに整理するには、必要なアセンブリごとにフォルダーを作成し、各アセンブリに属するスクリプトを該当するフォルダーに移動します。その後、Assembly Definition アセットを作成 してアセンブリのプロパティを指定します。
Unity は、Assembly Definition アセットを含むフォルダーのすべてのスクリプトを取得し、アセットで定義された名前やその他の設定を使用してアセンブリにコンパイルします。子フォルダーに独自の Assembly Definition か Assembly Reference アセットがない限り、同じアセンブリ内のすべての子フォルダーにあるスクリプトも含まれます。
既存のアセンブリに子ではないフォルダーのスクリプトを含むには、子ではないフォルダーに Assembly Reference アセットを作成し、ターゲットのアセンブリを定義する Assembly Definition アセットを参照するように設定します。例えば、エディターフォルダーがどこにあるかにかかわらず、プロジェクト内のすべてのエディターフォルダーのスクリプトを独自のアセンブリにまとめることができます。
Unity はアセンブリの依存関係に基づいてアセンブリのコンパイルを行います。コンパイルの順番を指定することはできません。
プロジェクトで使用されるアセンブリ間の参照は、Assembly Definition オプションを使用して制御できます。Assembly Definition の設定には以下があります。
ノート: Assembly Definition で作成されたアセンブリのクラスは、定義済みのアセンブリで定義された型を使用できません。
デフォルトでは、定義済みのアセンブリは、Assembly Definition で作成されたアセンブリ (1) や、プラグインとしてプロジェクトに加えられたプリコンパイルされたアセンブリ (2) など、他のすべてのアセンブリを参照します。また、Assembly Definition アセットで作成したアセンブリは、自動的にすべてのプリコンパイルされたアセンブリを参照します (3)。
デフォルトの設定では、定義済みのアセンブリのクラスは、プロジェクトの他のアセンブリで定義されたすべての型を使用できます。同様に、Assembly Definition アセットを使用して作成したアセンブリは、プリコンパイルされた (プラグイン) アセンブリで定義されたすべての型を使用できます。
Assembly Definition アセットの Inspector で [Auto Referenced オプション] をオフにすることで、定義済みアセンブリからアセンブリが参照されないようにすることができます。Auto Referenced (自動参照) をオフにすると、アセンブリのコードを変更したときに定義済みアセンブリが再コンパイルされなくなります。しかし、定義済みアセンブリがこのアセンブリのコードを直接使用できなくなるということも意味します。詳しくは、[Assembly Definition プロパティ] を参照してください。
同様に、プラグインアセットの Plugin Inspector の Auto Referenced プロパティ をオフにすると、プラグインアセンブリが自動的に参照されないようにすることができます。これは、定義済みのアセンブリと、Assembly Definition を使って作成したアセンブリの両方に影響します。詳細は、Plugin Inspector を参照してください。
プラグイン の Auto Referenced をオフにすると、Assembly Definition アセットの Inspector で明示的に参照できるようになります。アセットの Override References オプションを有効にして、プラグイン への参照を加えます。Assembly Definition プロパティを参照してください。
ノート: プリコンパイルされたアセンブリに対して、明示的な参照を宣言することはできません。定義済みのアセンブリは、自動参照されたアセンブリのコードのみを使用できます。
アセンブリの循環的な参照は、あるアセンブリが 2 つ目のアセンブリを参照し、さらにその 2 つ目のアセンブリが最初のアセンブリを参照する場合に存在します。このようなアセンブリ間の循環的な参照は許可されておらず、“Assembly with cyclic references detected” (循環的な参照を持つアセンブリが検知されました) というメッセージでエラーとして報告されます。
通常、このようなアセンブリ間の循環的な参照は、アセンブリで定義されたクラス内の循環的な参照が理由で発生します。同じアセンブリのクラス間の循環参照は技術的には問題ありませんが、異なるアセンブリのクラス間の循環参照は許可されません。循環参照エラーが発生した場合は、循環参照を削除するか、相互に参照しているクラスを同じアセンブリ内に置くようにコードをリファクタリングする必要があります。
Assembly Definition アセットを作成するには以下を行います。
Unity はプロジェクト内のスクリプトを再コンパイルして、新しいアセンブリを作成します。終了すると、新しい Assembly Definition の設定を変更することができます。
Assembly Definition を含むフォルダー内のスクリプトは、子フォルダー内のスクリプトも含め (子フォルダーに独自の Assembly Definition または Assembly Reference アセットが含まれている場合を除く)、新しいアセンブリにコンパイルされ、以前のアセンブリから削除されます。
Assembly Definition Reference を作成します。
Project ウィンドウで、参照されるアセンブリに加えるスクリプトを含むフォルダーを探します。
フォルダーに Assembly Referenceアセットを作成します (メニュー:Assets > Create > Assembly Definition Reference)。
アセットに名前を付けます。
Unity はプロジェクト内のスクリプトを再コンパイルして、新しいアセンブリを作成します。終了すると、新しい Assembly Definition Reference の設定を変更することができます。
新しい Assembly Definition Reference アセットを選択して、そのプロパティを Inspector で表示します。
Assembly Definition プロパティを設定して、対象の Assembly Definition アセットを参照します。
クリック Apply。
Assembly Definition Reference アセットを含むフォルダーのスクリプトは、子フォルダー内のスクリプトも含め (子フォルダーに独自の Assembly Definition または Assembly Definition Reference アセットが含まれている場合を除く)、参照されるアセンブリにコンパイルされ、以前のアセンブリから削除されます。
特定のプラットフォーム用のアセンブリを作成するには、以下を行います。
新しい Assembly Definition Reference アセットを選択して、そのプロパティを Inspector で表示します。
Any Platform オプションをチェックし、除外する特定のプラットフォームを選択します。または、Any Platform のチェックを外し、対象とする特定のプラットフォームを選択することもできます。
Apply をクリックします。
アセンブリは、プラットフォーム用にプロジェクトをビルドする際に、選択されたプラットフォームに応じて含まれます (または除外されます)。
エディターアセンブリによって、エディタースクリプトを Editor という名のトップレベルのフォルダーだけではなく、プロジェクトのどこにでも置くことができます。
エディターコードを含むアセンブリをプロジェクトに作成するには、以下を行います。
テストアセンブリを使うと、Unity TestRunner でテストを書いて実行することができ、テストコードをアプリケーションと一緒に出荷するコードから別にしておくことができます。Unity は TestRunner を Test Framework パッケージ の一部として提供しています。Test Framework パッケージのインストールやテストアセンブリの作成方法については、Test Framework ドキュメント を参照してください。
別のアセンブリに含まれる C# の型や関数を使用するには、Assembly Definition アセットでそのアセンブリへの参照を作成する必要があります。
アセンブリ参照を作成するには以下を行います。
参照を必要とするアセンブリの Assembly Definition を選択して、そのプロパティを Inspector で表示します。
Assembly Definition References セクションで、+ ボタンをクリックして、新しい参照を追加します。
参照リストの中で新しく作成されたスロットに Assembly Definition アセットを割り当てます。
Use GUIDs オプションを有効にすると、新しい名前を反映するように他の Assembly Definition の参照を更新することなく、参照されている Assembly Definition アセットのファイル名を変更できます。(アセットファイルのメタデータファイルが削除された場合や、メタデータファイルをいっしょに移動せずにファイルを Unity エディターの外に移動させた場合は、GUID をリセットする必要があります)。
デフォルトでは、Assembly Definition を使用して作成されたプロジェクトのすべてのアセンブリは、すべてのプリコンパイルされたアセンブリを自動的に参照します。この自動参照は、アセンブリ内のコードが使用されていなくても、プリコンパイルされたアセンブリのいずれかを更新すると、すべてのアセンブリを再コンパイルする必要があります。この余分なオーバーヘッドを避けるために、自動参照をオーバーライドして、アセンブリが実際に使用するプリコンパイル済みライブラリのみを参照するよう指定します。
参照を必要とするアセンブリの Assembly Definition を選択して、そのプロパティを Inspector で表示します。
General セクションで、Override References オプションを有効にします。
Inspector の Assembly References セクションは、Override References がチェックされていると利用可能になります。
Assembly References セクションで、+ ボタンをクリックして、新しい参照を加えます。
空きスロットのドロップダウンリストを使って、プリコンパイルされたアセンブリへの参照を割り当てます。リストには、プロジェクトの Build Settings で現在設定されているプラットフォーム用のプロジェクトのすべてのプリコンパイルされたアセンブリが表示されます。(プリコンパイルされたアセンブリのプラットフォーム互換性は、Plugin Inspector で設定してください)。
Apply をクリックします。
プロジェクトをビルドする各プラットフォームで繰り返します。
プリプロセッサシンボルを使って、ゲームやアプリケーションのビルド (エディターの再生モードを含む) にアセンブリをコンパイルして加えるかどうかを制御することができます。Assembly Definition オプションの Define Constraints リストで、アセンブリを使用するために定義しなければならないシンボルを指定することができます。
Assembly Definition を選択すると、そのプロパティが Inspector に表示されます。
Define Constraints セクションで、+ ボタンをクリックすると、制約のリストに新しいシンボルが追加されます。
シンボル名を入力します。
名前の前に感嘆符を付けることで、シンボルを否定することができます。例えば、 !UNITY_WEBGL
という制約は、UNITY_WEBGL が定義されていない場合、アセンブリを含むことになります。
Apply をクリックします。
以下の記号を制約条件として使用できます。
スクリプトで定義されたシンボルは、定義する際に制約が満たされているかどうかを考慮しません。
詳細は 制約の定義 を参照してください。
プロジェクトが特定のパッケージやパッケージのバージョンを使用しているかどうかに応じて、アセンブリのさまざまなコードをコンパイルする必要がある場合には、 Version Defines リストにエントリを追加できます。このリストには、シンボルを定義する際のルールが記載されています。バージョン番号に対して、特定のバージョンまたはバージョンの範囲を確認する論理式を指定できます。
シンボルを条件付きで定義するには、以下のようにします。
Assembly Definition を選択すると、そのプロパティが Inspector に表示されます。
Version Defines セクションで、 + ボタンをクリックしてリストに新しいシンボルを加えます。
プロパティを設定します。
Expression outcome は、その式がどのバージョンを評価するかを示しています。
以下の例では、プロジェクトが Timeline 1.3.0 以降を使用する場合、シンボル USE_TIMELINE を定義します。
Apply をクリックします。
Assembly Definition で定義されたシンボルは、その定義のために作成されたアセンブリ内のスクリプトに対してのみ適用されます。
Version Defines リストを使って定義したシンボルは、Define Constraints として使用できます。そのため、あるパッケージの特定のバージョンがプロジェクトにインストールされている場合にのみ、アセンブリを使用するように指定することができます。
式を使って、正確なバージョンまたはバージョンの範囲を指定することができます。バージョン定義 式は、数学的な範囲表記を使用しています。角かっこ [] は、終点を含む範囲を示します。
[1.3,3.4.1]
は1.3.0 <= x <= 3.4.1
を評価します。
かっこ () は、終点を除いた範囲であることを示します。
(1.3.0,3.4)
は1.3.0 < x < 3.4.0
を評価します。
1 つの式の中で、両方の範囲タイプを混在させることができます。
[1.1,3.4)
は1.1.0 <= x < 3.4.0
を評価します。
(0.2.4,5.6.2-preview.2]
は0.2.4 < x <= 5.6.2.-preview.2
を評価します。
正確なバージョンを指定するには、角かっこに単一のバージョン指定子を示します。
[2.4.5]
はx = 2.4.5
を評価します。
ショートカットとして、範囲かっこを付けずに単一のバージョンを入力すると、その式はそのバージョン以降を含むことを示します。
2.1.0-preview.7
はx >= 2.1.0-preview.7
を評価します。
バージョン指定子は、[セマンティックバージョニング] 形式に従って、MAJOR.MINOR.PATCH-LABEL の 4 つの部分から構成されています。最初の 3 つの部分は常に数字ですが、ラベルは文字列です。プレビュー中の Unity パッケージは、preview
または preview.n
(n > 0
)、という文字列を使用します。式の中では、少なくともバージョンのメジャーとマイナーのコンポーネントを使用する必要があります。
ノート: 式にはスペースは許可されません。
C# スクリプトがどのアセンブリにコンパイルされているかを確認するには、以下の方法があります。
Unity Project ウィンドウで C# スクリプトファイルを選択すると、Inspector ウィンドウにそのプロパティが表示されます。
アセンブリのファイル名とAssembly Definition (存在する場合) は、Inspector の Assembly Information セクションに表示されます。
この例では、選択されたスクリプトは、Unity.Timeline.Editor の Assembly Definition アセットによって定義されたライブラリファイル Unity.Timeline.Editor.dll にコンパイルされます。
Unity では、ある特別な名前を持つフォルダー内のスクリプトは、他のフォルダー内のスクリプトとは異なる扱いになります。ただし、そのフォルダー内やその上のフォルダーに Assembly Definition アセットを作成すると、特別な扱いを受けなくなります。この変化は、Editor フォルダーを使用しているときに気づくかもしれません。Editor フォルダーは、プロジェクトあちこちにある可能性があります (コードの整理方法や、使用している Asset Store パッケージ によって異なります)。
Unity では通常、Editor という名前のフォルダーにあるスクリプトは、どこにあっても定義済みの Assembly-CSharp-Editor アセンブリにコンパイルされます。ただし、その下に Editor フォルダーがあるフォルダーに Assembly Definition アセットを作成すると、Unity はそれらの Editor スクリプトを定義済みの Editor アセンブリに入れることはなくなります。その代わりに、Assembly Definition で作成された新しいアセンブリに加えられますが、そこは本来の場所ではない場合があります。Editor フォルダーを管理するには、各 Editor フォルダーに Assembly Definition または Assembly Definition Reference アセットを作成して、それらのスクリプトを 1 つまたは複数の Editor アセンブリに配置します。エディターコード用のアセンブリの作成 を参照してください。
アセンブリ属性を使用して、アセンブリのメタデータプロパティを設定できます。慣習的に、アセンブリ属性ステートメントは AssemblyInfo.cs という名前のファイルに記述します。
例えば、以下のアセンブリ属性は、いくつかの .NET アセンブリメタデータ値、テストに役立つ InternalsVisibleTo 属性、プロジェクトをビルドする際に未使用のコードをアセンブリから削除する方法に影響する Unity 定義の Preserve 属性 を指定します。
[assembly: System.Reflection.AssemblyCompany("Bee Corp.")]
[assembly: System.Reflection.AssemblyTitle("Bee's Assembly")]
[assembly: System.Reflection.AssemblyCopyright("Copyright 2020.")]
[assembly: System.Runtime.CompilerServices.InternalsVisibleTo("UnitTestAssembly")]
[assembly: UnityEngine.Scripting.Preserve]
UnityEditor.Compilation 名前空間にある CompilationPipeline クラスを使用して、Unity がプロジェクトのためにビルドしたすべてのアセンブリ (Assembly Definition アセットに基づいて作成されたものを含む) に関する情報を取得できます。
例えば、次のスクリプトは、CompilationPipeline クラスを使用して、プロジェクトの現在の Player アセンブリをすべて列挙します。
using UnityEditor;
using UnityEditor.Compilation;
public static class AssemblyLister
{
[MenuItem("Tools/List Player Assemblies in Console")]
public static void PrintAssemblyNames()
{
UnityEngine.Debug.Log("== Player Assemblies ==");
Assembly[] playerAssemblies =
CompilationPipeline.GetAssemblies(AssembliesType.Player);
foreach (var assembly in playerAssemblies)
{
UnityEngine.Debug.Log(assembly.name);
}
}
}