こんにちは、株式会社Leon Gameworksの遠藤です。
第17回では、エディタ拡張として独自メニューを追加する手法を解説しました。今回はその応用として、追加したメニューから直接Editor Utility Widget(EUW)を起動する方法を紹介します。
0:動作環境
本記事はUE5.7.4を基に執筆しており、画面のスクリーンショットはエディタの言語設定を「英語」として撮影しています。
なお、本記事で作成するプロジェクト一式は、以下よりダウンロード可能です。
1:実行するEUWを作成
まず、メニューから起動するEditor Utility Widget(EUW)アセットを作成します。
今回はツールの起動までを解説するため、UIの見た目は何でも問題ありません。ここではボタンとテキストを配置しています。
2:エディタモジュールの作成
メニューの追加はエディタ上でのみ実行される処理のため、エディタ専用のモジュールを作成します。
{
"FileVersion": 3,
"EngineAssociation": "5.7",
"Category": "",
"Description": "",
"Modules": [
{
"Name": "EUTools21",
"Type": "Runtime",
"LoadingPhase": "Default",
"AdditionalDependencies": [
"Engine"
]
},
{
"Name": "EUTools21Editor",
"Type": "Editor",
"LoadingPhase": "PostEngineInit",
"AdditionalDependencies": [
"Engine",
"UnrealEd",
"Blutility",
"EditorSubsystem",
"CoreUObject"
]
}
],
"Plugins": [
{
"Name": "ModelingToolsEditorMode",
"Enabled": true,
"TargetAllowList": [
"Editor"
]
}
]
}
▲モジュールの追加
3:メニュー押下時の処理を作成
今回は、モジュール起動時に呼び出される StartupModule 関数内で、関連する処理をまとめて実装します。
StartupModule と ShutdownModule に加え、メニュー登録用の OnWindowMenuBarExtension 関数を定義します。
#pragma once
#include "CoreMinimal.h"
#include "Modules/ModuleManager.h"
class FExtender;
class FMenuBarBuilder;
class FEUTools21EditorModule : public IModuleInterface
{
public:
//~ Begin IModuleInterface Interface.
virtual void StartupModule() override;
virtual void ShutdownModule() override;
//~ End IModuleInterface Interface.
private:
/** メニューバーに拡張内容を登録 */
void OnWindowMenuBarExtension(FMenuBarBuilder& MenuBarBuilder);
private:
// メニューの拡張ポイント
TSharedPtr<FExtender> Extender;
};
▲EUTools21Editor.h
StartupModule でメニューを登録し、OnWindowMenuBarExtension が実行されるように設定します。
OnWindowMenuBarExtension 内では、UEditorUtilitySubsystem いうサブシステムをロードし、SpawnAndRegisterTab 関数を呼び出してEUWを起動します。
#include "EUTools21Editor.h"
#include "EditorUtilitySubsystem.h"
#include "LevelEditor.h"
#include "EditorUtilityWidgetBlueprint.h"
#define LOCTEXT_NAMESPACE "FEUTools21EditorModule"
void FEUTools21EditorModule::StartupModule()
{
if (IsRunningCommandlet())
{
return;
}
FLevelEditorModule& LevelEditorModule = FModuleManager::LoadModuleChecked<FLevelEditorModule>("LevelEditor");
Extender = MakeShared<FExtender>();
if (Extender.IsValid())
{
Extender->AddMenuBarExtension(
"Help",
EExtensionHook::After,
nullptr,
FMenuBarExtensionDelegate::CreateRaw(this, &FEUTools21EditorModule::OnWindowMenuBarExtension)
);
}
TSharedPtr<FExtensibilityManager> menuManager = LevelEditorModule.GetMenuExtensibilityManager();
if (menuManager.IsValid())
{
menuManager->AddExtender(Extender);
}
}
void FEUTools21EditorModule::ShutdownModule()
{
if (Extender.IsValid() && FModuleManager::Get().IsModuleLoaded("LevelEditor"))
{
FLevelEditorModule& LevelEditorModule = FModuleManager::LoadModuleChecked<FLevelEditorModule>("LevelEditor");
TSharedPtr<FExtensibilityManager> menuManager = LevelEditorModule.GetMenuExtensibilityManager();
if (menuManager.IsValid())
{
menuManager->RemoveExtender(Extender);
}
}
}
void FEUTools21EditorModule::OnWindowMenuBarExtension(FMenuBarBuilder& MenuBarBuilder)
{
MenuBarBuilder.AddMenuEntry(
LOCTEXT("Menu_OpenMyTool", "Open My Tool"),
LOCTEXT("ToolTip_OpenMyTool", "Open My Tool"),
FSlateIcon(),
FUIAction(FExecuteAction::CreateLambda([]()
{
UEditorUtilitySubsystem* EUSubsystem = GEditor->GetEditorSubsystem<UEditorUtilitySubsystem>();
if (UEditorUtilityWidgetBlueprint* euw = LoadObject<UEditorUtilityWidgetBlueprint>(nullptr, TEXT("/Game/EUW_MyTool.EUW_MyTool")))
{
EUSubsystem->SpawnAndRegisterTab(euw);
}
}))
);
}
#undef LOCTEXT_NAMESPACE
IMPLEMENT_MODULE(FEUTools21EditorModule, EUTools21Editor)
▲EUTools21Editor.cpp
ビルド後、メニューバーから実行すると、指定したパスのEUWが起動します。
4:まとめ
今回は、EUWを起動する処理について解説しました。今回はメニューバーからの実行を例に取り上げましたが、EUWから別のEUWを起動するなど汎用的に使える処理なので、ぜひ活用してみてください。
本記事で作成したプロジェクト一式は、以下よりダウンロード可能です。
株式会社Leon Gameworks
●公式サイト
www.leon-game.co.jp
●X(Twitter)
@Leon_Gameworks
トンコツ(遠藤俊太)
●トンコツ開発ブログ
shuntaendo.hatenablog.com
●X(Twitter)
@tonkotsu3656
TEXT_トンコツ(Leon Gameworks)
EDIT_小村仁美 / Hitomi Komura(CGWORLD)、オムライス駆