Version: 2020.1
言語: 日本語
プラットフォーム依存コンパイル
Assembly Definition のプロパティ

アセンブリの定義

Assembly Definition (アセンブリ定義) と Assembly Reference (アセンブリ参照) は、スクリプトをアセンブリにまとめるために作成するアセットです。

アセンブリとは C# のコードライブラリで、スクリプトによって定義されたコンパイル済みのクラスや構造体を含み、他のアセンブリへの参照も定義します。C# のアセンブリに関する一般的な情報は、Assemblies in .NET を参照してください。

デフォルトでは、Unity はほとんどすべてのゲームスクリプトを、定義済みの アセンブリ、Assembly-CSharp.dll にコンパイルします。(Unity は、いくつかのより小さな、特殊な定義済みのアセンブリ も作成します。)

この方法は小規模なプロジェクトには適していますが、プロジェクトにさらに多くのコードを追加すると、いくつかの欠点があります。

  • 1 つのスクリプトを変更するたびに、Unity は他のすべてのスクリプトを再コンパイルする必要があり、反復的なコード変更を行うと全体のコンパイル時間が長くなります。
  • どのスクリプトも他のスクリプトで定義された型に直接アクセスできるため、コードのリファクタリングや改善が難しくなる可能性があります。
  • すべてのスクリプトは、すべてのプラットフォーム用にコンパイルされます。

アセンブリを定義することで、コードを整理してモジュール性や再利用性を高めることができます。プロジェクトで定義したアセンブリ内のスクリプトは、デフォルトのアセンブリには加えられず、指定した他のアセンブリのスクリプトにアクセスのみを行います。

上の図は、プロジェクトのコードを複数のアセンブリに分割する方法を示しています。MainStuff を参照しており、その逆ではないため、Main のコードを変更しても Stuff のコードには影響しません。同様に、Library は他のアセンブリに依存していないので、Library のコードを別のプロジェクトでより簡単に再利用することができます。

ここでは、Assembly Definition と Assembly Definition Reference アセットの作成と設定してプロジェクトのアセンブリを定義する方法について説明します。

関連項目

アセンブリの定義

プロジェクトのコードをアセンブリに整理するには、必要なアセンブリごとにフォルダーを作成し、各アセンブリに属するスクリプトを該当するフォルダーに移動します。その後、Assembly Definition アセットを作成 してアセンブリのプロパティを指定します。

Unity は、Assembly Definition アセットを含むフォルダーのすべてのスクリプトを取得し、アセットで定義された名前やその他の設定を使用してアセンブリにコンパイルします。子フォルダーに独自の Assembly Definition か Assembly Reference アセットがない限り、同じアセンブリ内のすべての子フォルダーにあるスクリプトも含まれます。

既存のアセンブリに子ではないフォルダーのスクリプトを含むには、子ではないフォルダーに Assembly Reference アセットを作成し、ターゲットのアセンブリを定義する Assembly Definition アセットを参照するように設定します。例えば、エディターフォルダーがどこにあるかにかかわらず、プロジェクト内のすべてのエディターフォルダーのスクリプトを独自のアセンブリにまとめることができます。

Unity はアセンブリの依存関係に基づいてアセンブリのコンパイルを行います。コンパイルの順番を指定することはできません。

参照と依存関係

  • ある型 (クラスや構造体など) が他の型を使用する場合、最初の型は 2 番目の型に 依存 しています。Unity がスクリプトをコンパイルする場合、そのスクリプトが依存している型やその他のコードにもアクセスできなければなりません。同様に、コンパイルされたコードが実行される場合、その依存関係のコンパイルされたバージョンにアクセスできなければなりません。2 つの型が異なるアセンブリにある場合、依存する型を含むアセンブリは、依存する型を含むアセンブリへの 参照 を宣言しなければなりません。

プロジェクトで使用されるアセンブリ間の参照は、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 InspectorAuto Referenced プロパティ をオフにすると、プラグインアセンブリが自動的に参照されないようにすることができます。これは、定義済みのアセンブリと、Assembly Definition を使って作成したアセンブリの両方に影響します。詳細は、Plugin Inspector を参照してください。

プラグインAuto Referenced をオフにすると、Assembly Definition アセットの Inspector で明示的に参照できるようになります。アセットの Override References オプションを有効にして、プラグイン への参照を加えます。Assembly Definition プロパティを参照してください。

ノート: プリコンパイルされたアセンブリに対して、明示的な参照を宣言することはできません。定義済みのアセンブリは、自動参照されたアセンブリのコードのみを使用できます。

循環的な参照

アセンブリの循環的な参照は、あるアセンブリが 2 つ目のアセンブリを参照し、さらにその 2 つ目のアセンブリが最初のアセンブリを参照する場合に存在します。このようなアセンブリ間の循環的な参照は許可されておらず、“Assembly with cyclic references detected” (循環的な参照を持つアセンブリが検知されました) というメッセージでエラーとして報告されます。

通常、このようなアセンブリ間の循環的な参照は、アセンブリで定義されたクラス内の循環的な参照が理由で発生します。同じアセンブリのクラス間の循環参照は技術的には問題ありませんが、異なるアセンブリのクラス間の循環参照は許可されません。循環参照エラーが発生した場合は、循環参照を削除するか、相互に参照しているクラスを同じアセンブリ内に置くようにコードをリファクタリングする必要があります。

Assembly Definition アセットの作成

Assembly Definition アセットを作成するには以下を行います。

  1. Project ウィンドウで、アセンブリに加えるスクリプトを持つフォルダーを探します。
  2. フォルダーに Assembly Definition アセットを作成します (メニュー: Assets > Create > Assembly Definition)。
  3. アセットに名前を割り当てます。デフォルトでは、アセンブリファイルにはアセットに割り当てた名前が使用されますが、Inspector ウィンドウで名前を変更することができます。

Unity はプロジェクト内のスクリプトを再コンパイルして、新しいアセンブリを作成します。終了すると、新しい Assembly Definition の設定を変更することができます。

Assembly Definition を含むフォルダー内のスクリプトは、子フォルダー内のスクリプトも含め (子フォルダーに独自の Assembly Definition または Assembly Reference アセットが含まれている場合を除く)、新しいアセンブリにコンパイルされ、以前のアセンブリから削除されます。

Assembly Definition Reference アセットの作成

Assembly Definition Reference を作成します。

  1. Project ウィンドウで、参照されるアセンブリに加えるスクリプトを含むフォルダーを探します。

  2. フォルダーに Assembly Referenceアセットを作成します (メニュー:Assets > Create > Assembly Definition Reference)。

  3. アセットに名前を付けます。

    Unity はプロジェクト内のスクリプトを再コンパイルして、新しいアセンブリを作成します。終了すると、新しい Assembly Definition Reference の設定を変更することができます。

  4. 新しい Assembly Definition Reference アセットを選択して、そのプロパティを Inspector で表示します。

  5. Assembly Definition プロパティを設定して、対象の Assembly Definition アセットを参照します。

  6. クリック Apply

Assembly Definition Reference アセットを含むフォルダーのスクリプトは、子フォルダー内のスクリプトも含め (子フォルダーに独自の Assembly Definition または Assembly Definition Reference アセットが含まれている場合を除く)、参照されるアセンブリにコンパイルされ、以前のアセンブリから削除されます。

プラットフォーム固有のアセンブリの作成

特定のプラットフォーム用のアセンブリを作成するには、以下を行います。

  1. Assembly Definition アセットを作成 します。

  2. 新しい Assembly Definition Reference アセットを選択して、そのプロパティを Inspector で表示します。

  3. Any Platform オプションをチェックし、除外する特定のプラットフォームを選択します。または、Any Platform のチェックを外し、対象とする特定のプラットフォームを選択することもできます。

  4. Apply をクリックします。

アセンブリは、プラットフォーム用にプロジェクトをビルドする際に、選択されたプラットフォームに応じて含まれます (または除外されます)。

エディターコード用アセンブリの作成

エディターアセンブリによって、エディタースクリプトを Editor という名のトップレベルのフォルダーだけではなく、プロジェクトのどこにでも置くことができます。

エディターコードを含むアセンブリをプロジェクトに作成するには、以下を行います。

  1. プラットフォーム専用のアセンブリ をエディタースクリプトが含まれるフォルダーに作成してください。
  2. エディタープラットフォームのみを含めます。
  3. エディターのスクリプトが入っているフォルダーが他にもある場合は、それらのフォルダーに Assembly Definition Reference アセットを作成 し、このアセンブリ定義を参照するように設定します。

テストアセンブリの作成

テストアセンブリを使うと、Unity TestRunner でテストを書いて実行することができ、テストコードをアプリケーションと一緒に出荷するコードから別にしておくことができます。Unity は TestRunner を Test Framework パッケージ の一部として提供しています。Test Framework パッケージのインストールやテストアセンブリの作成方法については、Test Framework ドキュメント を参照してください。

別のアセンブリの参照

別のアセンブリに含まれる C# の型や関数を使用するには、Assembly Definition アセットでそのアセンブリへの参照を作成する必要があります。

アセンブリ参照を作成するには以下を行います。

  1. 参照を必要とするアセンブリの Assembly Definition を選択して、そのプロパティを Inspector で表示します。

  2. Assembly Definition References セクションで、+ ボタンをクリックして、新しい参照を追加します。

  3. 参照リストの中で新しく作成されたスロットに Assembly Definition アセットを割り当てます。

Use GUIDs オプションを有効にすると、新しい名前を反映するように他の Assembly Definition の参照を更新することなく、参照されている Assembly Definition アセットのファイル名を変更できます。(アセットファイルのメタデータファイルが削除された場合や、メタデータファイルをいっしょに移動せずにファイルを Unity エディターの外に移動させた場合は、GUID をリセットする必要があります)。

プリコンパイルされたプラグインアセンブリの参照

デフォルトでは、Assembly Definition を使用して作成されたプロジェクトのすべてのアセンブリは、すべてのプリコンパイルされたアセンブリを自動的に参照します。この自動参照は、アセンブリ内のコードが使用されていなくても、プリコンパイルされたアセンブリのいずれかを更新すると、すべてのアセンブリを再コンパイルする必要があります。この余分なオーバーヘッドを避けるために、自動参照をオーバーライドして、アセンブリが実際に使用するプリコンパイル済みライブラリのみを参照するよう指定します。

  1. 参照を必要とするアセンブリの Assembly Definition を選択して、そのプロパティを Inspector で表示します。

  2. General セクションで、Override References オプションを有効にします。

    InspectorAssembly References セクションは、Override References がチェックされていると利用可能になります。

  3. Assembly References セクションで、+ ボタンをクリックして、新しい参照を加えます。

  4. 空きスロットのドロップダウンリストを使って、プリコンパイルされたアセンブリへの参照を割り当てます。リストには、プロジェクトの Build Settings で現在設定されているプラットフォーム用のプロジェクトのすべてのプリコンパイルされたアセンブリが表示されます。(プリコンパイルされたアセンブリのプラットフォーム互換性は、Plugin Inspector で設定してください)。

  5. Apply をクリックします。

  6. プロジェクトをビルドする各プラットフォームで繰り返します。

条件付きでアセンブリを加える

プリプロセッサシンボルを使って、ゲームやアプリケーションのビルド (エディターの再生モードを含む) にアセンブリをコンパイルして加えるかどうかを制御することができます。Assembly Definition オプションの Define Constraints リストで、アセンブリを使用するために定義しなければならないシンボルを指定することができます。

  1. Assembly Definition を選択すると、そのプロパティが Inspector に表示されます。

  2. Define Constraints セクションで、+ ボタンをクリックすると、制約のリストに新しいシンボルが追加されます。

  3. シンボル名を入力します。

    名前の前に感嘆符を付けることで、シンボルを否定することができます。例えば、 !UNITY_WEBGL という制約は、UNITY_WEBGL が定義されていない場合、アセンブリを含むことになります。

  4. Apply をクリックします。

以下の記号を制約条件として使用できます。

  • Scripting Define Symbols 設定 (Project Settings の中の Player セクションにあります) で定義されたシンボル。 Scripting Define Symbols は、プロジェクトの Build Settings で現在設定されているプラットフォームに適用されます。複数のプラットフォーム用にシンボルを定義するには、それぞれのプラットフォームに切り替えて Scripting Define Symbols フィールドを個別に変更する必要があります。
  • Unity で定義されているシンボル。プラットフォーム依存のコンパイル を参照してください。
  • Assembly Definition アセットの Version Defines セクションで定義されたシンボル。

スクリプトで定義されたシンボルは、定義する際に制約が満たされているかどうかを考慮しません。

詳細は 制約の定義 を参照してください。

プロジェクトパッケージに基づくシンボルの定義

プロジェクトが特定のパッケージやパッケージのバージョンを使用しているかどうかに応じて、アセンブリのさまざまなコードをコンパイルする必要がある場合には、 Version Defines リストにエントリを追加できます。このリストには、シンボルを定義する際のルールが記載されています。バージョン番号に対して、特定のバージョンまたはバージョンの範囲を確認する論理式を指定できます。

シンボルを条件付きで定義するには、以下のようにします。

  1. Assembly Definition を選択すると、そのプロパティが Inspector に表示されます。

  2. Version Defines セクションで、 + ボタンをクリックしてリストに新しいシンボルを加えます。

  3. プロパティを設定します。

    • Resource: このシンボルを定義するためにインストールしなければならないパッケージまたはモジュールを選択します。
    • Define: シンボル名
    • Expression: 特定のバージョンまたはバージョンの範囲を評価する式。ルールに関しては バージョン定義式 を参照してください。

    Expression outcome は、その式がどのバージョンを評価するかを示しています。

    以下の例では、プロジェクトが Timeline 1.3.0 以降を使用する場合、シンボル USE_TIMELINE を定義します。

  4. 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.7x >= 2.1.0-preview.7 を評価します。

バージョン指定子は、[セマンティックバージョニング] 形式に従って、MAJOR.MINOR.PATCH-LABEL の 4 つの部分から構成されています。最初の 3 つの部分は常に数字ですが、ラベルは文字列です。プレビュー中の Unity パッケージは、preview または preview.n (n > 0)、という文字列を使用します。式の中では、少なくともバージョンのメジャーとマイナーのコンポーネントを使用する必要があります。

ノート: 式にはスペースは許可されません。

スクリプトがどのアセンブリに属しているかを調べる

C# スクリプトがどのアセンブリにコンパイルされているかを確認するには、以下の方法があります。

  1. Unity Project ウィンドウで C# スクリプトファイルを選択すると、Inspector ウィンドウにそのプロパティが表示されます。

  2. アセンブリのファイル名とAssembly Definition (存在する場合) は、InspectorAssembly Information セクションに表示されます。

この例では、選択されたスクリプトは、Unity.Timeline.Editor の Assembly Definition アセットによって定義されたライブラリファイル Unity.Timeline.Editor.dll にコンパイルされます。

特殊フォルダー

Unity treats scripts in folders with certain, special names differently than scripts in other folders. However, one of these folders loses its special treatment when you create an Assembly Definition asset inside it or in a folder above it. You might notice this change when you use Editor folders, which might be scattered throughout your Project (depending on how you organize your code and on the Asset packages you use).

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);
        }
    }
}
プラットフォーム依存コンパイル
Assembly Definition のプロパティ