環境
Unreal Engine 4.17.2
Visual Studio Community 2015
概要
今回はPluginではなく、Moduleの分割でビルドを早くしたりコードの結合度を下げたいとかそういう人向けです。
Plugin開発についての知見も得られると思います。
Moduleの追加
先ずは新規にModuleを追加する方法を説明します。
基本的にはTemplateからのPluginの作成とかで勝手に作られるのですが
BlankでC++プロジェクトを作成した状態から開始します。
今回はModuleSandboxというプロジェクトに
BattleSystemという新規Moduleを追加します。
手順①
追加したいModule名のフォルダをProject/Source以下に作成する。
手順②
[ProjectName].Build.cs
[ProjectName].cpp
[ProjectName].h
を手順①で作成したModuleNameフォルダにコピー
手順③
コピーした
[ProjectName].xxxを
[ModuleName].xxxに変更する
手順④
[ModuleName].Build.csのProjectNameの箇所をModuleNameに変更する
using UnrealBuildTool; // 変更前:public class ModuleSandbox : ModuleRules public class BattleSystem : ModuleRules { // 変更前:public ModuleSandbox(ReadOnlyTargetRules Target) : base(Target) public BattleSystem(ReadOnlyTargetRules Target) : base(Target) { PCHUsage = PCHUsageMode.UseExplicitOrSharedPCHs; PublicDependencyModuleNames.AddRange(new string[] { "Core", "CoreUObject", "Engine", "InputCore" }); PrivateDependencyModuleNames.AddRange(new string[] { }); } }
手順⑤
[ModuleName].cppのProjectNameの箇所をModuleNameに変更
Moduleのクラスを追加し、Moduleの種類を指定する。
// 変更前:#include "ModuleSandbox.h" #include "BattleSystem.h" #include "Modules/ModuleManager.h" // 追加 class FBattleSystemModule : public IModuleInterface { public: virtual void StartupModule() override { } virtual void ShutdownModule() override { } virtual bool IsGameModule() const override { return true; } }; // 追加終わり // 変更前:IMPLEMENT_PRIMARY_GAME_MODULE( FDefaultGameModuleImpl, ModuleSandbox, "ModuleSandbox" ); // 今回はGameModuleとして追加する。 // GameModule, Moduleの違いは次の章で解説します。 IMPLEMENT_GAME_MODULE(FBattleSystemModule, "BattleSystem"); // IMPLEMENT_MODULE(FBattleSystemModule, "BattleSystem");
IMPLEMENT_PRIMARY_GAME_MODULEはプロジェクト中に1つしか存在しません。
追加するModuleは全てPRIMARYを外す必要があります。
手順⑥
ExtraModuleNamesに追加Moduleを加える。
[ProjectName].Target.cs
[ProjectName].Editor.Target.cs
上記2つに変更を加えます。変更方法は同じです。
using UnrealBuildTool; using System.Collections.Generic; public class ModuleSandboxTarget : TargetRules { public ModuleSandboxTarget(TargetInfo Target) : base(Target) { Type = TargetType.Game; // 変更前:ExtraModuleNames.AddRange( new string[] { "ModuleSandbox" } ); ExtraModuleNames.AddRange( new string[] { "ModuleSandbox", "BattleSystem" } ); } }
手順⑦
uprojectにModuleを登録する。
[ProjectName].uprojectをテキストエディタで開き、追加Moduleの設定を加える。
{ "FileVersion": 3, "EngineAssociation": "4.17", "Category": "", "Description": "", "Modules": [ { "Name": "ModuleSandbox", "Type": "Runtime", "LoadingPhase": "Default" }, // 追加分 { "Name": "BattleSystem", "Type": "Runtime", "LoadingPhase": "Default" } // 追加終了 ] }
手順⑧
Solutionの更新
.uprojectを右クリックし、Generate Visual Studio project filesでslnの更新を行う。
エラーが出なければこれでModuleの追加が出来ています。
ソリューションを開いてSource以下に追加されていれば成功です。
GameModuleとModuleの違い
この辺りは少し面倒な話でUE4 C++本でも
”プラグインに対してのホットリロードには難ありというのが現時点での正直な感想です"と書かれています。
私はあまり不便だと感じていませんが、それはさて置き
先に結論だけ述べます。
GameModuleの場合はHotReloadの際にビルドに含まれます。
Moduleの場合はCompileボタンを押してもHotReloadが行われません。
Moduleの場合はWindow -> Developer Tools -> Modulesウィンドウから行う必要があります。
Recompileボタンを押下することでHotReloadが行われます。
他にも幾つか違いがあるとは思いますが、私が触ってみて分かった範囲について記述させていただきました。
PluginでもProjectの別Moduleの場合でも開発中にModuleとGameModuleを切り替えることが可能です。
ビルド時間をとりあえず短縮したい場合はModuleとして作成すれば良いと思われます。
Pluginの場合はModuleとして作成されます。
GameModuleの場合
#include "[ModuleName].h" #include "Modules/ModuleManager.h" class F[ModuleName]Module : public IModuleInterface { public: virtual void StartupModule() override { } virtual void ShutdownModule() override { } virtual bool IsGameModule() const override { return true; } }; IMPLEMENT_GAME_MODULE(F[ModuleName]Module, "[ModuleName]");
Moduleの場合
#include "[ModuleName].h" #include "Modules/ModuleManager.h" class F[ModuleName]Module : public IModuleInterface { public: virtual void StartupModule() override { } virtual void ShutdownModule() override { } virtual bool IsGameModule() const override { return false; } }; IMPLEMENT_MODULE(F[ModuleName]Module, "[ModuleName]");