Using tool menus for editor extension
This tutorial covers the use of tool menus to create a toolbar button in the level viewport. This button when clicked open up a Editor utility widget which you can use to make your own tool.
Let's create a toolbar button that opens an Editor Widget. This button is created at the engine startup by using the Run function provided by EditorUtilityClasses. On click, the button runs a console command which calls a custom event. This event opens our Editor Widget.
Create a content plugin
First create a content plugin, this step is not required.
Creating a plugin is recommended for reuse of your tool.
On the Menubar select Edit then Plugin a window pop, click New plugin.
- Finally select create plugin
Create the required Classes
Add a folder:
-
Right click the ContentBrowser
-
Select New Folder
-
Name it: "Tutorial"
Our Hook, our entry point
Right Click in the ContentBrowser then Select Editor Utility Blueprint like below
Then pick EditorUtilityObject
-
Call it BPU_TutoStartupHook
-
Right click on it and Copy Reference
Open Your project folder navigate to Config and edit DefaultEditorPerProjectUserSettings.ini and add:
[/Script/Blutility.EditorUtilitySubsystem]
StartupObjects="PasteYourReferenceHere"
Remove EditorUtilityBlueprint' from the pasted reference the final line should be like
StartupObjects="/MyToolTuto/Tutorial/BPU_TutoStartupHook.BPU_TutoStartupHook"
The widget
Create a Editor Utility Widget name it WBPU_ToolWidget
Blueprint setup
Create those variables names:
Now set the variables like below:
-
Menu
-
Type: Name
-
Value: LevelEditor.LevelEditorToolBar
-
-
Section
-
Type: Name
-
Value: MyTools
-
-
MenuEntry
-
Type: ToolMenuEntry
-
Value:
-
Name: Mytools
-
Type: ToolBarButton
-
UserInterfaceActionType: Button
-
-
-
Label
-
Type: Text
-
Value: MyTool
-
-
ToolTip
-
Type: Text
-
Value: Open MyTool
-
-
Icon
- Type: ScriptSlateIcon
-
OptionWidget
-
Type: EditorUtilityWidgetBlueprint
-
Value: WBPU_ToolWidget
-
-
OptionWidgetID
- Type: Name
Copy the following graph:
Add a space after KISMETEVENT
and before OpenWidgetOptions
Now you may try it: Close the editor and restart your project if a button appear like this:
Success if you can click the button and the widget window appear
If there is no button first verify DefaultEditorPerProjectUserSettings.ini add a print string node on the Event Run. Reload and search the OutputLog for the string. If you did not have to change the ini file to see the string the error may be one of the following in OutputLog:
-
"Hook menu not found" the variable menu value is wrong
-
"LogToolMenus: Warning: Toolbar 'LevelEditor.LevelEditorToolBar', item 'Mytools', type not currently supported: X" the variable MenuEntry is not setup correctly
If the button doesn't open the widget verify the append Node
-
If on click you see "Failed to find an object named 'BPU_TutoStartupHook_C_0OpenWidgetOptions'." You miss a space before OpenWidgetOptions
-
If the error is silent "Cmd: KISMETEVENTBPU_TutoStartupHook_C_0 BPUOpenWidgetOptions" You miss a space after KISMETEVENT
Further reading
Other menus
Now that you know how to create a toolbar button you can now do it for any kind of menu
e.g: You can add button in the main menu bar change the variable Menu to LevelEditor.MainMenu.Window and set accordingly MenuEntry Type to MenuEntry
you can search in the engine source for UToolMenus::Get()->RegisterMenu to find the available menus.
Specific Classes
-
This is a topic i do not master well.
-
A lot of the engine code is not exposed to blueprint
-
It may be change in future
You can create a button for a specific class to do that you need a context to find a matching class wich is provided by the ToolMenuEntryScript class you may subclass this and pass it to the MenuEntry ScriptObject variable.
Your ToolMenuEntryScript subclass has native event CanExecute and ConstructMenuEntry those provide the necessary context
Passing a scriptObject to the MenuEntry bypass the button creation from the node AddMenuEntry and as result it fire ConstructMenuEntry event.
-
Implement icon for the button
-
Support for other menus and specific classes
-
Support for Section
An Alternative Approach
Hi - thanks for the above information - but I believe there's an easier way.
I suggest you follow this example: https://twitter.com/MilkyEngineer/status/1379644300108029955
In summary:
- You create an a Blueprint called
Editor Utility Tool Menu Entry
- You then set menu position and icon in the details of that new BP (the example also shows how to grab names for pre-existing icons in the
Editor Style
style set) - You then add a couple of events to the event graph of this BP, a custom event called Run (and add the same ini entry to add it to Startup Objects as identified above) and overide the Execute event to call
Spawn and Register Tab
If working with UE 5.3:
- In step 3 of the example, don't update the ini file, use the following Console Command:
ToolMenus.Edit
- If nothing shows up make sure you haven't messed up either the menu name or the section name, and in 5.3 the exact hierarchy/menu names seem to have changed around a bit. I used
Menu = LevelEditor.LevelEditorToolBar.User
and it worked (after having screwed it up and nothing showing up)
Same final results. Less code to add to your BP.
I hope this helps.