こんにちは、Unityエンジニアのオオバです。
Assembly Definition(アセンブリディフィニション)」って聞いたことはあるけど使ったことはないという方いらっしゃるのではないでしょうか。
Assembly Definitionを使うことでソースコード同士の依存関係を簡単に設定することができます。
ソースコード的に絶対に依存関係を作ってはいけないものってりますよね。そのようなルールはAssembly Definitionを使うとシステムとして作ることが可能です。具体的に言うと、 意図しない依存関係を作ろうとするとエラーになる ということです。
そこで本記事では Assembly Definition入門 ということでAssembly Definitionを使ったことがない方に向けた内容となっています。
- Assembly Definitionを使ったことがない
- これからAssembly Definitionを使ってみたい
- 前々からAssembly Definitionに興味があった
- Assembly Definitionの事を知りたかった
このような方にはピッタリの記事になっているのでぜひ最後まで読んでみてください。
👉DOTweenの教科書を読んでUnityアニメーションをプログラミングしてみよう!
- Unityエディタが作り出すアセンブリとは何か?
- Assembly Definitionによって何が改善されるのか?
- Assembly Definitionの具体的な使い方
- Assembly Definitionの性質を理解しよう
- 1.Assembly Definitionで設定したコードからAssembly-CSharpはアクセス不可
- 2.Assembly-CSharp、Assembly-CSharp-EditorからはAssembly Definitionへアクセス可能
- 3.Assembly Definitionの適用範囲
- 指定のソースコードがどのアセンブリに所属しているか調べる方法
- Assembly Definitionまとめ
Unityエディタが作り出すアセンブリとは何か?
Unityエディタ起動してソースコードを作成すると生まれるファイルがあります。それが「アセンブリ」です。アセンブリとはC#ソースコードをコンパイルしたDLLファイルです。
具体的には Library/ScriptAssemblies
フォルダ内にコンパイルされるたびに更新されます。
このアセンブリファイルはAssembly Definition以前は非常に大雑把な管理でした。
- ランタイムコード・・・Assembly-CSharp.dll
- エディタコード・・・Assembly-CSharp-Editor.dll
という形で大きなDLLファイルが作成されていたのです。
全てのランタイムコードが含まれるためクラス間の依存関係が必然的に分離できず事故りやすい状況になっていました。またちょっとしたコード修正でも全ソースコードのコンパイルが走るため、待機時間も長くなってしまいます。
そこでAssembly Definitionが登場したのです。
Assembly Definitionによって何が改善されるのか?
Assembly Definitionによって何が改善されたのかと言うと、一言で表すと 「アセンブリの分割」 です。
今まで1つの巨大なアセンブリに詰め込まれていたソースコードが、 開発者が自由に決めることができるようになった のです。
これにより依存関係の明確化とコンパイル時間が改善されます。
Assembly Definitionの具体的な使い方
実際にAssembly Definitionを使ってみないと理解しづらいため、さっそく具体的な使い方について解説していきます。既存プロジェクトへ導入を前提に話を進めていきます。
Assembly Definitionの導入方法
今回は既存のプロジェクトであるQRコードシステムにAssembly Definitionを導入します。
QRコードシステムにはランタイムコード(Runtimフォルダ)とEditor拡張コード(Editorフォルダ)が混在。そして外部ライブラリとしてUniTaskを使用しています。
早速Assembly Definitionを導入します。導入のためにAssembly Definitionファイルを作成します。
メニューAssets -> Create -> Scripting -> Assembly Definition
からAssembly Definitionファイルを作成しました。
ランタイムコードにAssembly Definitionファイルを追加し、QRCode.Runtimeと名付けました。
すると次のようなUniTaskのエラーがConsoleに表示されます。
Assets/Project/QRCode/Runtime/QRReader.cs(1,7): error CS0246: The type or namespace name 'Cysharp' could not be found (are you missing a using directive or an assembly reference?)
これは今回作成したAssembly Definitionによってアセンブリが分離し、 UniTaskへアクセスができなくなった ことを指したエラーです。
今まで「Assembly-CSharp」にまとめられていたQRCodeが独自のアセンブリとして独立したために起きました。
つまり UniTaskへの依存関係を作る必要が出てきた ということです。Assembly Definitionを使う際は、モジュール間の 依存関係を手動で設定 する必要があることを覚えておきましょう。
Assembly Definition同士の依存関係の作成
ではAssembly Definition同士の依存関係を構築する方法を解説していきます。依存関係の構築はAssembly DefinitionのInspectorウィンドウから行います。具体的にはAssembly Definition Referencesに依存したいAssembly Definitionを選択するだけです。
UniTaskに依存する場合は、Assembly Definition Referencesの「+」ボタンからUniTaskのAssembly Definitionを選択します。するとコンパイルエラーがなくなりました。無事にQRCodeがUniTaskに 依存できた ことができたということです。
重要設定「Auto Referenced」とは?
Assembly DefinitionのInspectorには 「Auto Referenced」 という設定があります。実はかなり重要なチェックボックスです。というのもAuto ReferencedはON/OFFで大きな違いがあるからです。
Auto ReferencedがONの状態では Assembly-CSharp、Assembly-CSharp-Editorからアクセスすることができます。 OFFにするとできません。
つまりUnityプロジェクト内の一部の機能をAssembly Definitionで別アセンブリにしたけど、そのままアクセスを継続したい場合「Auto Referenced」のチェックが必要です。
Auto ReferencedをOFFにするとアクセスできなくなりコンパイルエラーを起こしてしまいます。
上図の通り、自作アセンブリ「Hoge」のAuto ReferencedをOFFにすると、Assembly-CSharp、またはAssembly-CSharp-Editorからアクセスできなくなります。
ぜひAuto Referencedの特徴をしっかりと理解しておきましょう。
Assembly-CSharp、またはAssembly-CSharp-Editorからアクセスしないアセンブリは 積極的に「Auto Referenced」はOFFにした方が良い です。
理由は2つあります。
- 設計的にAssembly-CSharpまたはAssembly-CSharp-Editorから依存しない事を明示的に示せること
- Assembly-CSharpまたはAssembly-CSharp-Editorにコード修正が入った場合にコンパイルされコンパイル時間が伸びるため
コンパイル対象から外れるとその分コンパイル時間は短縮するのです。設計的な安全性とコンパイル時間が短縮のためにも可能な限りAuto Referencedは外した方が良さそうです。
Assembly Definitionの性質を理解しよう
Assembly Definitionを適当に設定していると、本来アクセスしたいオブジェクトにアクセスできない、エラーが直らないといったトラブルが発生します。
Assembly Definitionの性質、挙動は正しく理解しておく必要があるのです。
ここでは重要なAssembly Definitionの性質を3つ紹介します。
1.Assembly Definitionで設定したコードからAssembly-CSharpはアクセス不可
Unityプロジェクト内で一部だけAssembly Definitionを導入するケースで起きがちなトラブルです。Assembly Definitionで独立させたは良いが、独立した側のソースコードから Assembly-CSharpにアクセスできなくて困る ケースです。
Assembly Definitionの性質上、Assembly Definitionで独立させたコードからAssembly-CSharp内のコードにアクセスする方法はありません。設計から見直すか、Assembly Definitionをやめるかといった選択が求められるでしょう。
今回途中からAssembly Definitionを導入を前提に話を進めていますが、 理想は開発初期から導入 しておくことをオススメします。
2.Assembly-CSharp、Assembly-CSharp-EditorからはAssembly Definitionへアクセス可能
もう1つの性質はAssembly-CSharp、Assembly-CSharp-Editorからは独立したAssembly Definitionのコードにアクセスできるということです。
Assembly Definitionからはアクセスできませんが、Assembly-CSharpからはアクセスすることはぜひ覚えておいてください。
しかしAssembly-CSharpからAssembly Definitionにアクセスできる条件があります。それは「Auto Referenced」がtrueのときだけです。
Assembly DefinitionのInspectorウィンドウ内「Auto Referenced」にチェックが入っていないとAssembly-CSharp、Assembly-CSharp-Editorからアクセスできなくなるため注意してください。
もちろん「Auto Referenced」をOFFにした方が、参照が少なくなる分、コード修正時のコンパイル時間は短くなりやすいです。
3.Assembly Definitionの適用範囲
Assembly Definitionファイルがどの範囲までを同一アセンブリに含めるのか知っておく必要があります。
結論、フォルダ配下がAssembly Definitionの対象となります。
上図の例ではRuntimeフォルダ内、Editorフォルダ内にそれぞれAssembly Definitionファイルが格納されているため、それぞれアセンブリとして分割されます。
Assembly Definitionファイルが格納されたフ ォルダ配下が対象 になるということを覚えておきましょう。
以上の性質を頭に入れつつAssembly Definitionと付き合っていきましょう。
指定のソースコードがどのアセンブリに所属しているか調べる方法
Assembly Definitionを使っていると指定のソースコードがどのアセンブリに所属しているのか確認したくなるときが出てきます。
そんなときはリフレクションを使うと簡単に確認可能です。
var assemblyName = typeof(SampleClass).Assembly.FullName;
Debug.Log(assemblyName);
上記のように Assembly.FullName
でアセンブリ名を取得できます。
Assembly Definitionまとめ
本記事ではAssembly Definition入門として紹介してきました。記事の内容を簡単にまとめます。
①Assembly Definitionはアセンブリを分離する
②Assembly Definitionはフォルダ配下をまとめる
③Auto ReferencedはAssembly-CSharp、Assembly-CSharp-Editorからのアクセス可否を決める
④Assembly Definition同士で参照関係を構築して参照を解決する
⑤Assembly Definitionで分離した分コンパイル時間が短くなるかも
こんな感じです。
Assembly Definitionを使用することでソースコード内の依存関係のルール化をシステムとして導入することが可能になりました。
これによりチーム開発のトラブルを下げることができます。また、アセンブリが分離したことでソースコードの修正によるコンパイル時間短縮に繋がります。
小規模プロジェクトにAssembly Definitionはあまり効果を発揮しづらいですが、大規模プロジェクトになればなるほどAssembly Definitionの恩恵は大きくなるため、一度導入を検討してみてはいかがでしょうか。
この記事があなたのゲーム開発の役に立ったら嬉しいです。

筆者のXをフォローしよう
Unityオブジェクトの描画順の制御って難しいですよね。
この度、Unityの描画順を体系的に学べる「Unity描画順の教科書」を執筆しました。
Unityの描画順を基礎から学びたい方はぜひ確認してみてください!
→ Unity描画順の教科書
最後まで読んでいただきありがとうございました!
すばらしいAssembly Definitionライフをお過ごしください。
- Unity6000.0.32f1