かすてらすねお。

見聞録的ななにか。

【UE5】C++でエディタのプレビュー開始直前に処理を行うサンプル

Unreal Editor でプレビュー実行を開始する直前に処理を C++ で書く必要があったので、やり方を調べました。

「FEditorDelegates を使えばいい」*1 という記事は見かけるのですが、具体的な実装方法が見当たらなかったのでまとめました。

この記事のサンプルコードを使うと、

  • Play In Editor(PIE):すべてのゲームロジックを含めたモード
  • Simulate in Editor(SIE):物理シミュレーションのみ行うモード

の開始直前タイミングを補足し、それぞれを区別して処理を行えるようになります。

具体的には FEditorDelegates クラスのデリゲートにイベントを登録して動かします。

検証環境

  • Win64 Editor
  • UE 5.3.2(Launcher)

実装方法

MyPluginプラグインの MyPluginEditorモジュールへの実装例です。

Build.csファイル MyPlugin.Build.cs

実装のポイント

  • (1)依存モジュールの追加(Core, UnrealEd)
    • Core モジュール: FDelegateHandle を定義する Delegates/IDelegateInstance.h をインクルードしている CoreMinimal.h 向け
    • UnrealEd モジュール: FEditorDelegates 向け
using UnrealBuildTool;

public class MyPluginEditor : ModuleRules
{
    public MyPluginEditor(ReadOnlyTargetRules Target) : base(Target)
    {
        PCHUsage = PCHUsageMode.UseExplicitOrSharedPCHs;

        // (1)依存モジュールの追加(Core, UnrealEd)
        PublicDependencyModuleNames.AddRange(new string[] {
            "Core",
            "CoreUObject",
            "Engine"
        });

        PrivateDependencyModuleNames.AddRange(new string[] {
            "UnrealEd"
        });
    }
}

ヘッダーファイル MyPluginModule.h

実装のポイント

  • (2)イベントハンドラを宣言する
  • (3)FDelegateHandle のために必要(CoreMinimal.h)
  • (4)登録したイベントのハンドルを宣言する(FDelegateHandle型)
#pragma once

// (3)FDelegateHandle のために必要(CoreMinimal.h)
#include "CoreMinimal.h"

#include "Modules/ModuleManager.h"

class FMyPluginEditorModule : public IModuleInterface
{
public:
    virtual void StartupModule() override;
    virtual void ShutdownModule() override;

private:
    // デリゲートの登録と削除を関数化すると修正しやすい
    void AddDelegates();
    void RemoveDelegates();
    // (2)イベントハンドラを宣言する(bool型の引数を1つとる)
    void OnPreBeginPreview(bool bIsSimulating);

private:
    // (4)登録したイベントのハンドルを宣言する(FDelegateHandle型)
    FDelegateHandle PreBeginPIEHandle;
};

実装ファイル MyPluginModule.cpp

実装のポイント

  • (5)bool 型の引数を1つとるイベントハンドラを書く
  • (6)PIEモードと SIEモードを判別する(bIsSimulating パラメータ)
  • (7)FEditorDelegates のために必要(Editor.h)
  • (8)モジュールの開始時にイベントハンドラを登録する(FEditorDelegates::PreBeginPIE.AddRaw)
  • (9)モジュールの終了時にイベントハンドラを削除する(FEditorDelegates::PreBeginPIE.RemoveRaw)
#include "MyPluginEditor.h"

// (7)FEditorDelegates のために必要(Editor.h)
#include "Editor.h"

void FMyPluginEditorModule::StartupModule()
{
    AddDelegates();
}

void FMyPluginEditorModule::ShutdownModule()
{
    RemoveDelegates();
}

// (8)モジュールの開始時にイベントハンドラを PreBeginPIEへ登録する
void FMyPluginEditorModule::AddDelegates() 
{
    PreBeginPIEHandle = FEditorDelegates::PreBeginPIE.AddRaw(this, &FMyPluginEditorModule::OnPreBeginPIE);
}

// (9)モジュールの終了時にイベントハンドラを PreBeginPIEから削除する
void FMyPluginEditorModule::RemoveDelegates() 
{
    FEditorDelegates::PreBeginPIE.Remove(PreBeginPIEHandle);
}

// (5)bool 型の引数を1つとるイベントハンドラを書く
void FMyPluginEditorModule::OnPreBeginPreview(bool bIsSimulating)
{
 // (6)PIEモードと SIEモードを判別する(bIsSimulating パラメータ)
    if (bIsSimulating)
    {
        UE_LOG(LogTemp, Log, TEXT("Simulate In Editor (SIE) セッション開始直前"));
    }
    else
    {
        UE_LOG(LogTemp, Log, TEXT("Play In Editor (PIE) セッション開始直前"));
    }
}

IMPLEMENT_MODULE(MyPlugin::FMyPluginEditorModule, MyPluginEditor)

実装のポイントまとめ

  • Build.csファイル

    • (1)依存モジュールの追加(Core, UnrealEd)
  • ヘッダーファイル

    • (2)イベントハンドラを宣言する
    • (3)FDelegateHandle のために必要(CoreMinimal.h)
    • (4)登録したイベントのハンドルを宣言する(FDelegateHandle型)
  • 実装ファイル

    • (5)bool 型の引数を1つとるイベントハンドラを書く
    • (6)PIEモードと SIEモードを判別する(bIsSimulating パラメータ)
    • (7)FEditorDelegates のために必要(Editor.h)
    • (8)モジュールの開始時にイベントハンドラを登録する(FEditorDelegates::PreBeginPIE.AddRaw)
    • (9)モジュールの終了時にイベントハンドラを削除する(FEditorDelegates::PreBeginPIE.RemoveRaw)

Follow me on X: @suneo3476Web