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 をクリックします。
以下の記号を制約条件として使用できます。
スクリプトで定義されたシンボルは、定義する際に制約が満たされているかどうかを考慮しません。
詳細は 制約の定義 を参照してください。
If you need to compile different code in an assembly according to whether a project uses specific versions of Unity or of a package, you can add entries to the Version Defines list. This list specifies rules for when a symbol should be defined. For version numbers, you can specify a logical expression that evaluates to a specific version or a range of versions.
シンボルを条件付きで定義するには、以下のようにします。
Select the Assembly Definition asset for the assembly to view its properties in the Inspector.
Version Defines セクションで、 + ボタンをクリックしてリストに新しいシンボルを加えます。
プロパティを設定します。
The Expression outcome shows which versions the expression evaluates to. If the outcome displays, Invalid, then expression syntax is incorrect.
The following example defines the symbol, USE_TIMELINE_1_3, if the project uses Timeline 1.3 and defines, USE_NEW_APIS, if the project is opened in Unity 2021.2.0a7, or later:
Apply をクリックします。
Assembly Definition で定義されたシンボルは、その定義のために作成されたアセンブリ内のスクリプトに対してのみ適用されます。
Note that you can use the symbols defined using the Version Defines list as Define Constraints. Thus you could specify that an assembly should only be used when specific versions of a given package are also installed in the project.
You can use expressions to specify an exact version or a range of versions. A Version Define expression uses mathematical range notation.
A square bracket, “[]” designates that the range includes the endpoint:
[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
を評価します。
Note: No spaces are allowed in an expression. No wildcard characters are supported.
Current versions of Unity (and all versions that support Assembly Definitions) use a version designator with three parts: MAJOR.MINOR.REVISION, for example, 2017.4.25f1
, 2018.4.29f1
, and 2019.4.7f1
.
Release type designators are compared as follows:
a < b < f = c < p < x
In other words, an alpha release is considered earlier than a beta, which is earlier than a normal (f) or China (c) release. A patch release is always later than a normal or China release with the same revision number and an experimental release is later than any other release type. Note that experimental releases do not use an incremental number at the end.
Unity version numbers are allowed to have a suffix after the REVISION component, such as 2019.3.0f11-Sunflower
. Any suffixes are ignored for the purpose of comparing versions.
As an example, the following expression includes any 2017 or 2018 version of Unity, but not any version in 2019 or later:
[2017,2019)
Package and module version designators have four parts, following the Semantic Versioning format: MAJOR.MINOR.PATCH-LABEL. The first three parts are always numbers, but the label is a string. Unity packages in preview use the string, preview
or preview.n
, where n > 0
.
See Package Versioning for more information about package version numbers.
For example, the following expression includes all versions of a package with MAJOR.MINOR versions between 3.2 and 6.1 (inclusive):
[3.2,6.1]
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);
}
}
}