モジュール とは、Unreal Engine のソフトウェア アーキテクチャの基本的な構成要素です。これにより、特定のエディタ ツール、ランタイム機能、ライブラリなどの機能がコードのスタンドアローンのユニットに「カプセル化」されます。
すべてのプロジェクトとプラグインには、デフォルトで独自の プライマリ モジュール がありますが、これら以外のモジュールを定義してコードを整理することができます。
このページでは、モジュールの構造と Unreal Engine プロジェクトにおけるその利点について概要を説明します。
Unreal Engine のモジュールは C++ 20 モジュールに関連するものではありません。
モジュールを使用する利点
プロジェクトの整理にモジュールを使用することの利点は次のとおりです。
-
モジュールでは適切なコードの分離が強制的に実行され、機能をカプセル化し、コードの内部を隠します。
-
モジュールは、それぞれ異なるコンパイル ユニットとしてコンパイルされます。つまり、変更されたモジュールのみがコンパイルされ、大規模なプロジェクトにおいてはビルド時間が大幅に短縮されます。
-
モジュールは依存関係グラフにおいて互いにリンクされており、Include What You Use (IWYU) スタンダードに沿って、ヘッダに含まれるものが、実際に使用するコードに限定されます。これは、プロジェクトで使用しないモジュールがコンパイル処理から安全に除外されることを意味します。
-
ランタイム時に特定のモジュールをロード/アンロードするタイミングを制御できます。これにより、どのシステムが利用可能でアクティブかを管理することで、プロジェクトのパフォーマンスを最適化できるようになります。
-
モジュールは、プロジェクトをどのプラットフォームに向けてコンパイルするかなどの特定の条件に基づいて、プロジェクトに含めたり除外したりできます。
まとめると、モジュールを使ったベスト プラクティスを実践することで、すべてのコードを単一のモジュールに含めた場合よりも、プロジェクトのコードをよりうまく整理し、コンパイル時の効率と再利用性を高めることができます。
キャラクターを設定する
以下は、モジュールを最初からビルドして実装するための概要です。この手順に従うことで、プロジェクトにデフォルトで含まれるプライマリ モジュールとは別のゲームプレイ モジュールを作成できます。
- プロジェクトの「Source」フォルダ内のトップ レベルに、モジュール用のディレクトリを作成します。このディレクトリには当該のモジュールと同じ名前を付けます。
モジュールは、階層の深さにかかわらず、「Source」フォルダ内のあらゆるサブディレクトリに含めることができます。このように、サブディレクトリをモジュールのグループ化に使用できます。
-
モジュールのルート ディレクトリ内に「
[モジュール名].Build.cs
」ファイルを作成し、これを使って他のモジュールとの依存関係を定義します。こうすることで、Unreal のビルド システムでモジュールを発見できるようになります。 -
モジュールのルート ディレクトリ内に「Private」と「Public」というサブフォルダをそれぞれ作成します。
-
モジュールの「Private」フォルダ内に「
[モジュール名]Module.cpp
」ファイルを作成します。これを使って、モジュールや、Unreal Engine がモジュール管理に使用する他の共通の関数を開始/停止する方法を提供します。 -
モジュールがロードされるタイミングとその方法を制御するには、
.uproject
または.uplugin ファイル
にモジュールのコンフィギュレーション情報を追加します。この情報には、モジュールの名前、タイプ、互換性のあるプラットフォーム、ロード フェーズが含まれます。 -
当該のモジュールを使用するあらゆるモジュールに対して、このモジュールを依存関係として「
Build.cs
」ファイル内に記述します。これには、プロジェクトのプライマリ モジュールの「Build.cs
」ファイルが含まれることもあります。 -
「
[モジュール名].Build.cs
」ファイルを変更したときや、フォルダ間でソース ファイルを移動したときには、常に IDE のソリューション ファイルを生成します。次のいずれかを実行します。-
GenerateProjectFiles.bat
を実行する。 -
プロジェクトの「
.uproject
」ファイルを右クリックし、[Generate Project Files (プロジェクト ファイルを生成)] をクリックする。 -
Unreal Editor で [File (ファイル)] > [Refresh Visual Studio Project (Visual Studio プロジェクトをリフレッシュ)] をクリックする。
-
これらのコンポーネントとその設定方法については、このページを読み進めてください。モジュールのより詳しい設定方法については、「Creating a Gameplay Module」を参照してください。
モジュールの構造を理解する
すべてのモジュールは、プロジェクトまたはプラグインの「Source 」ディレクトリに含める必要があります。モジュールのルート フォルダには、当該のモジュールと同じ名前を付けます。
それぞれのモジュールのルート フォルダ内に「[モジュール名].Build.cs
」ファイルがあり、その C++ コードが「Private」と「Public」の両フォルダに含まれている必要があります。
次は、モジュールに推奨されるフォルダ構造の例です。
- [モジュール名]
- Private
- [モジュール名]Module.cpp
- すべての .cpp ファイルとプライベート ヘッダ
- Public
- すべてのパブリック ヘッダ
- [モジュール名].Build.cs
- Private
「Build.cs」ファイル内で依存関係を設定する
Unreal のビルド システムでは、IDE のソリューションファイルではなく、プロジェクトの「Target.cs
」ファイルとモジュールの「Build.cs
」ファイルに基づいてプロジェクトをビルドします。
IDE ソリューション ファイルはコードの編集時に自動生成されますが、Unreal Build Tool (UBT) ではプロジェクトのコンパイル時にこれを無視します。
すべてのモジュールは、Unreal のビルド システムで認識できるよう、それぞれのモジュールのルート ディレクトリ内に「[モジュール名].Build.cs
」ファイルが必要です。
「[モジュール名].Build.cs
」ファイル内では、モジュールを ModuleRules クラスから継承されたクラスとして定義する必要があります。次は、シンプルな「Build.cs
」ファイルの例です。
Sample ModuleTest.Build.cs File
using UnrealBuildTool;
public class ModuleTest:ModuleRules
{
public ModuleTest(ReadOnlyTargetRules Target) : base(Target)
{
PrivateDependencyModuleNames.AddRange(new string[] {"Core"});
}
}
「Build.cs
」ファイルを設定する際は、主に PrivateDependencyModuleNames
と PublicDependencyModuleNames
の各リストを使用します。これらのリストにモジュールの名前を追加すると、当該モジュールのコードで利用可能なモジュールが設定されます。
たとえば、「Slate」と「SlateUI」というモジュールの名前をプライベート依存関係リストに加えると、当該モジュール内に Slate UI クラスを含められるようになります。
プライベートおよびパブリックの依存関係
モジュールからのクラスをパブリックに使用する、つまりパブリック .h
ファイル内などで使用する場合は、PublicDependencyModuleNames
リストを使用してください。こうすることで、当該のモジュールに依存する他のモジュールで、問題なくそのヘッダ ファイルを含めることができるようになります。
プライベートのみで使用するモジュールについては (.cpp
ファイル内で使用するなど)、その名前を PrivateDependencyModuleNames
リストに含めます。プライベート依存関係ではプロジェクトのコンパイル時間を削減できるため、使用できる場合はこれを優先してください。
ヘッダ ファイル内で前方宣言を使用することで、多くの依存関係をパブリックではなくプライベートにすることができます。
「Private」と「Public」フォルダを使用する
モジュールが通常の C++ モジュール ( .uproject
または .uplugin
で ModuleType
が External
に設定されていない) である場合は、C++ 関連のファイルをモジュールのルート ディレクトリ内にある「Private」と「Public」の各サブフォルダに配置する必要があります。
これらは、C++ コード内の Private
、Public
、または Protected
アクセス指定子とは関連がありませんが、他のモジュール対する当該モジュールの使用可能性を制御します。これらのフォルダを使用する際は、すべての .cpp
ファイルを「Private」フォルダに配置します。ヘッダ (.h
) ファイルは、以下のガイドラインに従って「Private」と「Public」の両フォルダに配置します。
ヘッダ ファイルを「Private」フォルダに配置すると、そのコンテンツはそれを所有するモジュール以外のモジュールには公開されません。このフォルダ内にあるクラス、構造体、列挙型変数には、同じモジュール内にある他のクラスからはアクセスすることができますが、他のモジュールのクラスからは使用できません。
ヘッダを「Public」フォルダに配置した場合、Unreal のビルド システムでは、現在のモジュールとの依存関係を持つ他のモジュールにそのコンテンツを公開します。外部のモジュールのクラスでは、「Public」フォルダに含まれるクラスを拡張できるため、「Public」フォルダに含まれるクラス、構造体、列挙型変数を使って変数および参照を作成することができます。Private
、Public
、Protected
の各指定子は、通常どおりに関数と変数で使用できるようになります。
他との依存関係を持たないモジュールの場合は、「Private
」フォルダおよび「Public
」フォルダを使用する必要はありません。これらのフォルダ外にあるコードは、「Private」フォルダにある場合と同様に動作します。この一例として、多くの場合に一連の依存関係の末端にある、ゲームのプライマリ モジュールが挙げられます。
「Public
」フォルダと「Private
」フォルダ内にそれぞれサブフォルダを作成することで、コードをさらに整理することもできます。「Public
」内に作成する新規フォルダについては、それに対応する同じ名前のフォルダを「Private
」にも作成してください。同様に、「Public
」に配置するすべてのヘッダ ファイルについては、それに対応する .cpp
ファイルを「Private
」内の適切な (対応する) フォルダに常に配置してください。
Unreal Editor の新規クラス ウィザードで新しいクラスを作成した場合は、これらのフォルダ間での「並列構造」が自動的に作成されます。
モジュールを C++ で実装する
モジュールを C++ プロジェクト全体に公開するには、IModuleInterface
を拡張してクラスを作成し、このクラスを IMPLEMENT_MODULE
マクロに提供する必要があります。
このもっとも簡単な実装方法では、まずモジュールの「Private」ディレクトリ内に .cpp
ファイルを作成し、これに「[モジュール名]Module.cpp
」と名前を付けます。他のすべての「#include
」宣言の後に IMPLEMENT_MODULE
マクロを呼び出して、FDefaultModuleImpl
をそのクラスとして提供します。
ModuleTestModule.cpp
#include "Modules/ModuleManager.h"
IMPLEMENT_MODULE(FDefaultModuleImpl, ModuleTest);
FDefaultModuleImpl
は IModuleInterface
を拡張する空のクラスです。より複雑な実装の場合は、この .cpp
ファイルに実装するクラスを独自に作成できます。
IModuleInterface
には、GameInstance
クラスの Startup
や Shutdown
関数に似た、モジュールのロード/アンロードをトリガーするいくつかの関数が備わっています。
モジュールをプロジェクトで使用する
新しい Unreal Engine プロジェクトまたはプラグインを作成した際は、独自のプライマリ モジュールがプロジェクトの「Source
」内に自動的に設定されます。外部のモジュールをプロジェクトのプライマリ モジュールの「Build.cs
」ファイルに加えることで、これらのモジュールをプロジェクトに含めることができます。
たとえば、「MyProject」というタイトルのプロジェクトで Gameplay Tasks システムを使用するには、「MyProject.Build.cs
」を開き、依存関係として「GameplayTasks」` モジュールを加えます。
Unreal Build Tool では、コンパイル速度を最適化するために、プロジェクトの一連の依存関係に含まれるモジュールのみをコンパイルします。つまり、モジュールがプロジェクトで使用するどの「Build.cs
」ファイルにも含まれない場合、このモジュールはコンパイル時にスキップされます。
モジュールのロード方法を制御する
「.uproject
」ファイルと「.uplugin
」ファイルには、プロジェクトに含まれるモジュールとそれらのロード方法を定義する Modules
リストが含まれています。
プロジェクト ファイルを再作成した際は、モジュールのエントリが (存在しない場合は) このリストに自動的に追加されます。これらのモジュールが依存関係に含まれていることを想定しているためです。このリストのエントリは次のようになります。
"Modules": [
{
"Name":"ModuleTest",
"Type":"Runtime",
"LoadingPhase":“Default”,
},
{
"Name":“ModuleTestEditor”,
"Type":“Editor”,
}
]
ほとんどのゲームプレイ モジュールでは単にそれらの Name が含まれ、それらの Type は Runtime
に設定されます。LoadingPhase が定義されていない場合は Default
に設定されます。他のモジュール タイプやロード フェーズ、さらにはモジュールがロードする、またはロードされないプラットフォームを制御する追加のパラメータがあります。
使用可能なモジュール タイプについては、「EHostType::Type」に関する API ドキュメントを参照してください。
もっともよく使われるモジュール タイプは Runtime
と Editor
であり、それぞれゲーム内クラスおよびエディタ専用クラスで使用されます。
ロード フェーズの詳細については、「ELoadingPhase::Type」に関する API ドキュメントを参照してください。
Default
ロード フェーズはプロジェクトのほとんどのゲームプレイ モジュールに適していますが、プラグインの場合はより早い段階でロードする必要がある場合があります。Unreal Editor でプラグインの C++ クラスが見つからないエラーが頻繁に発生する場合は、それらを PreDefault
に設定してみてください。
このリストで使用される他のパラメータには次のようなものがあります。
パラメータ | 説明 |
---|---|
WhitelistPlatforms /BlacklistPlatforms (配列) | リストに含まれるプラットフォームでのコンパイルにモジュールを含めるか除外します。プラットフォームの文字列の例としては、Win32 、Win64 、Mac 、Linux 、Android 、IOS があります。 |
WhitelistTargets / BlacklistTargets (配列) | リストに含まれるビルド ターゲットでのコンパイルにモジュールを含めるか除外します。使用可能なビルド ターゲットには、Game 、Server 、Client 、Editor 、Program があります。 |
WhitelistTargetConfigurations / BlacklistTargetConfigurations (配列) | リストに含まれるビルド コンフィギュレーションでのコンパイルにモジュールを含めるか除外します。使用可能なターゲット コンフィギュレーションには、Debug 、DebugGame 、Development 、Shipping 、Test があります。 |
WhitelistPrograms / BlacklistPrograms (配列) | 特定のプログラム名でのコンパイルにモジュールを含めるか除外します。 |
AdditionalDependencies (配列) | 当該モジュールに必要な追加の依存関係を指定します。代わりに、これを「Build.cs 」ファイルで指定してください。 |