🐡

【UE5】C++でツールメニューに自作の項目を追加する

2024/12/01に公開

概要

この記事は一人アドベントカレンダー by ダリアの1日目の記事です。

【UE4】【UE5】”真”Blueprintだけで、Editor上にメニューを追加する【★★★】
今回はこちらの方の記事を参考にエディタ拡張を行っていたのですが、C++でやる方法が知りたくなり、調べたことをまとめて記事にしました。

想定してるイメージはこういうイメージをしてます

環境

UE5.4.4

やり方

Build.csにToolMenusを追加します

ExampleToolMenusExtension.Build.cs
using UnrealBuildTool;

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

        PublicDependencyModuleNames.AddRange(
            new string[]
            {
                "Core",
            }
        );

        PrivateDependencyModuleNames.AddRange(
            new string[]
            {
                "CoreUObject",
                "Engine",
                "Slate",
                "SlateCore",
+               "ToolMenus"
            }
        );
    }
}

追加したらToolMenusを用いてメニューの拡張をしてきます。
Moduleクラスを以下のように改造します。(ExampleToolMenusExtensionはプロジェクト名orプラグイン名と思っていただければ幸いです)

ExampleToolMenusExtension.h
#pragma once

#include "CoreMinimal.h"
#include "Modules/ModuleManager.h"

class FExampleToolMenusExtensionModule : public IModuleInterface
{
public:
    virtual void StartupModule() override;
    virtual void ShutdownModule() override;
    
+   //以下追加
+   void RegisterMenuExtension();
+   static FText GetMenuTitle();
+   static void ExecuteMenu();
};

ExampleToolMenusExtension.cpp
#include "ExampleToolMenusExtension.h"

#include "ToolMenus.h"
#include "ToolMenuSection.h"

#define LOCTEXT_NAMESPACE "ExampleToolMenusExtensionModule"

void FExampleToolMenusExtensionModule::StartupModule()
{
+	if (!IsRunningCommandlet() && !IsRunningGame() && FSlateApplication::IsInitialized())
+	{
+		UToolMenus::Get()->RegisterStartupCallback(FSimpleMulticastDelegate::FDelegate::CreateRaw(this, &ExampleToolMenusExtensionModule::RegisterMenuExtension));
+	}
}

void FExampleToolMenusExtensionModule::ShutdownModule()
{
+	if (!IsRunningCommandlet() && !IsRunningGame() && !IsRunningDedicatedServer())
+	{
+		UToolMenus::UnregisterOwner(this);
+	}
}

void FExampleToolMenusExtensionModule::RegisterMenuExtension()
{
+   UToolMenu* Menu = UToolMenus::Get()->ExtendMenu("LevelEditor.MainMenu.Tools");
+   //専用の項目を作る
+   FToolMenuSection& Section = Menu->AddSection("ExampleToolMenusExtension", LOCTEXT("ExampleToolMenusExtension", "ExampleToolMenusExtension"));
+   //項目に対して要素を追加する
+   Section.AddEntry(FToolMenuEntry::InitMenuEntry(
+       "ValidateData",
+       //項目名
+       TAttribute<FText>::Create(&GetMenuTitle), 
+       //ツールチップ
+       LOCTEXT("", ""), 
+       //アイコン
+       FSlateIcon(FAppStyle::GetAppStyleSetName(), "DeveloperTools.MenuIcon"),
+       //選択されたときのイベント
+       FUIAction(FExecuteAction::CreateStatic(&ExampleToolMenusExtensionModule::ExecuteMenu))
+   ));
}

+FText FExampleToolMenusExtensionModule::GetMenuTitle()
+{
+	return LOCTEXT("ExampleToolMenusExtensionModule", "ExampleToolMenusExtension");
+}

+void FExampleToolMenusExtensionModule::ExecuteMenu()
+{
+}

#undef LOCTEXT_NAMESPACE
    
IMPLEMENT_MODULE(FExampleToolMenusExtensionModule, ExampleToolMenusExtension)

エディタ拡張対象の見つけ方

今回対象となっているエディタ拡張の名称はLevelEditor.MainMenu.Toolsという部分になります。
これの見つけ方以下の記事を参考にしました。

【UE4】Blueprintだけで、Editor上にメニューを追加する【★★★】

それっぽい名前だったのが今回使ったLevelEditor.MainMenu.Toolsでした。
その名前を元にUnrealのソースコードで検索した所、DataValidationModule.cppというソースコードが丁度やりたいことをやっていたので参考にして実装しました。

Discussion