関連ブログ
- [UE4][UE5]開発環境の容量を少しでも減らす 2024.08.14UE
- [UE5] PushModel型のReplicationを使い、ネットワーク最適化を図る 2024.05.29UE
- [UE5]マテリアルでメッシュをスケールする方法 2024.01.17UE
CATEGORY
2014.08.28UE4UE/ C++
改訂バージョン: Unreal Engine 4.21 |
UE4のC++コードプロジェクトを利用していると、レベルに依存しない初期化、後処理、毎フレームの更新を行いたいケースが出てくるのではないかと思います。
今回は、その記述方法をご紹介します。
C++コードを含むプロジェクトを作成すると、プロジェクト名と同名のcppファイルが自動生成されます。
今回は「MyCodeProject」という名前で解説を進めたいと思います。
MyCodeProject.cpp の内容は、デフォルトでは下記のようになっています。
1 2 |
#include "MyCodeProject.h" #include "Modules/ModuleManager.h" |
IMPLEMENT_PRIMARY_GAME_MODULE( FDefaultGameModuleImpl, MyCodeProject, “MyCodeProject” );
この4行目の IMPLEMENT_PRIMARY_GAME_MODULE というマクロが、モジュールの登録を行うマクロです。
UE4のC++実行ファイルは、モジュール単位で管理されます。
UE4本体も複数のモジュールから成っており、ゲームプロジェクトもその1つとして読み込まれ、実行される、という形です。(要はWindowsではdllです)
仕組み的には、ゲームモジュールはプラグインと同様のものになります。
FDefaultGameModuleImpl がゲームモジュールを管理するクラスなのですが、簡単のために、デフォルトでは何もしないクラスで登録されます。
これを拡張することで、モジュールがロードされた直後と、モジュールが開放される直前のタイミングを取得することが可能です。
下記のように拡張します。
1 2 3 4 5 6 7 8 |
#include "MyCodeProject.h" #include "Modules/ModuleManager.h" class FMyCodeProjectModule : public FDefaultGameModuleImpl { public: virtual void StartupModule() { } virtual void ShutdownModule() { } }; |
IMPLEMENT_PRIMARY_GAME_MODULE(FMyCodeProjectModule, MyCodeProject, “MyCodeProject”);
これで、ゲームモジュールがロードされた直後のタイミングと、開放される直前のタイミングに処理を記述することが可能になります。
レベルに依存せずに毎フレームの更新を行うには、FTickableGameObjectを使用します。
今回は、ゲームモジュールの初期化時から開放までの間、毎フレームTickが呼び出されるようにしたいと思います。
コードは下記のようになります。
1 2 3 4 5 6 7 8 9 10 11 12 13 |
#include "MyCodeProject.h" #include "Modules/ModuleManager.h" class FMyTickableGameObject : public FTickableGameObject { public: virtual TStatId GetStatId() const { RETURN_QUICK_DECLARE_CYCLE_STAT(FMyTickableGameObject, STATGROUP_Tickables); } virtual bool IsTickable() const { return true; } virtual void Tick(float DeltaTime) { UE_LOG(LogTemp, Log, TEXT("MyTick %f"), DeltaTime); } }; static FMyTickableGameObject* MyTickableObject = NULL; |
class FMyCodeProjectModule : public FDefaultGameModuleImpl
{
public:
virtual void StartupModule()
{
MyTickableObject = new FMyTickableGameObject();
}
virtual void ShutdownModule()
{
delete MyTickableObject;
MyTickableObject = NULL;
}
};
IMPLEMENT_PRIMARY_GAME_MODULE(FMyCodeProjectModule, MyCodeProject, “MyCodeProject”);
これで、FMyTickableGameObject::Tick()が毎フレーム呼び出されていることが確認出来ると思います。
この方法での更新では、ゲームロジックに関わる処理は行わない方が良いでしょう。
アプリケーション起動中を通して必要な、OSや各種SDKとのやり取りを行う処理を、一元化して書くには便利な方法です。