この記事では、Unreal Engine 4 で自作したモジュールを使う方法について説明しています。
執筆時に扱った Unreal Engine のソースコードのバージョンは 4.25.4
プラットフォームは Windows 10 (64ビット版) を対象としています。
ビルドに使用したアプリ(IDE)は Microsoft Visual Studio 2017 です。
以降、Unreal Engine 4 を UE4 と略記します。
モジュールの作成方法と、プロジェクトへの追加方法は以下の記事が参考になります。
ググると同様の記事が他にもいくつかヒットしますが、記事通りに試してみて、こちらが一番楽でした。
多分、「わざわざ書くまでもないよな?」という判断なのだと邪推します。
プロジェクトに追加したモジュールは、他のクラスと同じように扱うことができます。
以下に、自作したモジュールを UObject と関連付けて、UE4 のガーベジコレクタに乗るようにした上で、インスタンスを生成するところまでのサンプルソースコードを記載します。
TestModule.h
// Copyright 1998-2017 Epic Games, Inc. All Rights Reserved. #pragma once #include "CoreMinimal.h" #include "Modules/ModuleInterface.h" #include "Modules/ModuleManager.h" // 追加 #include "TestModule.generated.h" // ここまで /** * The public interface to this module */ class ITestModule : public IModuleInterface { public: /** * Singleton-like access to this module's interface. This is just for convenience * Beware of calling this during the shutdown phase, though. Your module might have been unloaded already. * * @return Returns singleton instance, loading the module on demand if needed */ static inline ITestModule& Get() { return FModuleManager::LoadModuleChecked< ITestModule >( "TestModule" ); } /** * Checks to see if this module is loaded and ready. It is only valid to call Get() if IsAvailable() returns true. * * @return True if the module is loaded and ready to use */ static inline bool IsAvailable() { return FModuleManager::Get().IsModuleLoaded( "TestModule" ); } }; // 追加 UCLASS() class TESTMODULE_API UMyTestModule : public UObject, public ITestModule { GENERATED_BODY() }; // ここまで
TestModule.cpp
変更なし
自作したモジュールに追加するコードは以上です。
次は、自作したモジュールを呼び出すコードを追加します。
ソースファイルを新規作成するのは面倒なので、既存のソースファイルに追記します。
Blank(椅子とテーブルだけ置かれているテンプレートプロジェクト)でプロジェクトを作成しました。
プロジェクト名はデフォルトの MyProject です。
なので、自作モジュール以外の既存のソースコードは、MyProject か MyProjectGameModeBase しかありません。
GameMode ならプレイ時に勝手に実行してくれるので、MyProjectGameModeBase に、自作モジュールを呼び出すコードを追加することにしました。
MyProjectGameModeBase.h
// Copyright Epic Games, Inc. All Rights Reserved. #pragma once #include "CoreMinimal.h" #include "GameFramework/GameModeBase.h" #include "MyProjectGameModeBase.generated.h" /** * */ UCLASS() class MYPROJECT_API AMyProjectGameModeBase : public AGameModeBase { GENERATED_BODY() }; // 追加 UCLASS() class AMyGameMode : public AMyProjectGameModeBase { GENERATED_BODY() public: AMyGameMode(); }; // ここまで
MyProjectGameModeBase.cpp
// Copyright Epic Games, Inc. All Rights Reserved. #include "MyProjectGameModeBase.h" // 追加 #include "UObject/UObjectGlobals.h" #include "TestModule.h" AMyGameMode::AMyGameMode() { UMyTestModule* Module = CreateDefaultSubobject<UMyTestModule>(FName("UMyTestModule"), true); UE_LOG(LogTemp, Log, TEXT("AMyGameMode::AMyGameMode() : Module=%p"), Module); } // ここまで
「ワールドセッティング」→「Game Mode」→「ゲームモードオーバーライド」で、AMyGameMode に変更します。
プレイすると、アウトプットログに以下のログが出力されます。
自作モジュールの使い方は、他のクラスと全く変わらないことが確認できました。
どおりで、どこにも説明がないはずです。
有名なヒストリアさんの記事に書いてありました。
クラスや関数を外部公開しないなら、クラスの宣言部でクラス名の前に
モジュール名_API
を付ける必要はないようですが、そもそも外部公開の外部って具体的にどの範囲?というのが疑問です。
外部と呼べそうな範囲はいくつかあります。
- 自作モジュールのクラス以外
- 自作モジュールのソースファイル以外
- 自作モジュールのフォルダ以外
- 別の Unreal Project
上記のうち、3. と 4. が、この場合の「外部」になります。
今回作った TestModule のフォルダ以外は全て外部です。
今回のサンプルでは、TestModule の外部にある MyProjectGameModeBase で TestModule を使っているので、モジュール名_API(TESTMODULE_API) が必要になりました。
そのため、TestModule のクラス宣言が
class TESTMODULE_API UMyTestModule
となっています。
TestModule のフォルダ内でしか使わないなら、TESTMODULE_API は不要です。
「【UE4】自作モジュールの使い方」への1件のフィードバック