BLOGブログ

2015.06.17UE4UE/ C++

[UE4] モジュールについて

改訂バージョン: Unreal Engine 4.21

今回は、UE4のC++コードをビルドする際に知っておきたい、モジュールの概念と実装方法について説明します。

完全にプログラマ向けですし、簡単なゲームを作るだけであれば知らなくても動かせる内容ではありますが、UE4をしっかりと使いこなすためには、把握しておいた方がよい内容です。

 

1.モジュールとは

UE4のC++コードは、「モジュール」と呼ばれる単位で、「UnrealBuildTool」を通してビルドされます。

この時「モジュール」毎に、Windowsではdllファイル、Macではdylibファイルが作られます。

これは、エンジン内部のコードでも、プラグインでも、ゲームプロジェクトでも共通です。

 

ゲームプロジェクトもプラグインも、それぞれが複数のモジュールを含むことが出来ます。

また、ビルド構成によってロードするモジュールを切り替えることが出来るため、エディタ専用のモジュールや開発用ビルド専用のモジュールを作ることで、#ifdefよりも大きくまとまった単位で、機能を切り分けることが出来ます。

 

メインメニューの [Window] -> [Developer Tools] -> [Modules] から、エンジン内部も含めた、全てのモジュールの一覧を確認することが出来ます。

 

2.モジュールを構成するファイル群

通常、プロジェクトにC++コードを追加すると、下記のようなフォルダ構成が作成されます。

Source
  |- MyProject.Target.cs
  |- MyProjectEditor.Target.cs
  |- MyProject
       |- MyProject.Build.cs
       |- MyProject.cpp
       |- MyProject.h
       |- ...

最初に登録されるモジュールの名前は、プロジェクト名と同一です。なので、上記のフォルダ構成は、実は下記のような意味になっています。

Source
  |- [プロジェクト名].Target.cs
  |- [プロジェクト名]Editor.Target.cs
  |- [モジュール名]
       |- [モジュール名].Build.cs
       |- [モジュール名].cpp
       |- [モジュール名].h
       |- ...

 

このとき、[モジュール名]フォルダ以下が、1つのモジュールとしてビルドされる範囲となります。

また、Sourceフォルダの追加だけでなく、.uprojectファイル(プラグインの場合は .upluginファイル)に下記のような記述が追加されます。

 

これが、このプロジェクトに含まれるモジュールを列挙している記述になります。

標準のエンジン機能のみでゲームを開発する場合には、1つのゲームモジュールがあれば十分ですが、 エディタ拡張を行う場合等には複数のモジュールに分けておくと便利な場合があります。

 

モジュールの”Type”には、いくつかの種類がありますが、主に使用するのは”Runtime”と”Editor”です。

(詳しくは公式ドキュメントを参照して下さい)

“Runtime”は、ゲームの実行時に必要になるモジュールで、常にロードされます。

“Editor”は、ゲームの実行時には必要ない、エディタ上での動作に必要なモジュールです。 パッケージされたゲームや、Shippingビルド時にはビルドされず、当然ロードもされません。

 

以前の記事で、プラグインによるエディタ拡張の方法をご紹介しましたが、このような内容のコードは本来”Editor”モジュールに実装すべきです。

また、独自のアセットを実装する方法でご紹介した内容では、本来はアセットクラス自体は”Runtime”モジュールに、FactoryやAssetTypeActionsといったエディタ用の機能は”Editor”モジュールに実装すべきです。

SpriteStudioプラグインでも、そのようにモジュールの分割を行っています。

 

3.エディタモジュールの実装例

では、実際にゲームプロジェクトにエディタモジュールを追加する手順をご紹介します。

今回は、”MyProjectEd”という名前のエディタ専用モジュールを追加します。

 

まず、先ほどの .uprojectファイルを下記のように修正します。

 

続いて、モジュール用のソースコードを追加します。

最低限必要なコードは、下記の通りです。

Source
  |- MyProjectEd
       |- MyProjectEd.Build.cs
       |- MyProjectEd.cpp
       |- MyProjectEd.h

ファイルの内容は、最初の「MyProject」モジュールからコピーして、モジュール名の部分だけ置換すればOKです。

 

続いて、Source / MyProjectEditor.Target.cs の SetupBinaries関数内ExtraModuleNamesを、以下のように修正します。

 

ココに記述するか、記述されたモジュールから間接的に参照されるかしないと、コードだけを追加したモジュールはビルドの対象になりませんので注意して下さい。

[プロジェクト名].Target.cs がランタイム用、[プロジェクト名]Editor.Target.cs がエディタ起動時用です。

 

これで、エディタ用モジュールが実装出来ました。

最低限のエディタ用モジュールを実装したサンプルプロジェクトを添付しておきますので、参考にして下さい。

 

4.外部モジュールから参照される機能

次に、実装したモジュールの機能を外部から使用する方法です。

おそらく、MyGameEdモジュールからMyGameモジュールの機能を使用したいことがあるでしょう。

 

外部モジュールへの参照は、.Build.csファイルの PublicDependencyModuleNames にモジュール名を記述することで追加出来ます。

しかし、そもそも参照先のモジュールが機能を外部公開していなければ、モジュール外から関数呼び出しやクラスの参照を行うことが出来ません。

 

外部公開するクラスや関数の宣言の前に

[モジュール名]_API

というマクロを追加することで、その機能をモジュール外に公開することが出来ます。

例えば “MyProject”モジュールであれば”MYPROJECT_API”、”UnrealEd”モジュールであれば”UNREALED_API”、”Paper2D”モジュールであれば”PAPER2D_API”といった形です。

エンジン本体や標準プラグインのコードをみると、あちこちでこのマクロを見つけることが出来ると思います。

 

どこからも参照される予定のないモジュールであれば、この宣言は不要ですが、C++からのアクセスを考慮したプラグインや、エディタモジュールを追加する予定のゲームのランタイムモジュールなどでは、適切に外部公開を行う必要があります。

 

モジュールの概念は、UE4の設定を知るうえで非常に重要です。

UE4のC++プロジェクトを適切に設計/運用するためにも、しっかりと押さえておきましょう。