Hey,
I am working on a UE4 project for university and I am creating a small editor plugin to procedurally generate buildings.
Unfortunately I can not seem to find a way to start the editor utility widget by pressing the toolbar button/using C++.
I already tried to use CreateWidget, but it does not seem to work with EditorUtilityWidgets.
I realized that there is very little information to find for this problem.
Does anyone have an idea how to run an EditorUtilityWidget via C++?
Unfortunately I can’t get the reference to the Widget right.
Do you also know how to properly reference the EditorWidget, since I can’t seem to get it to work with ConstructorHelper::ClassFinder.
This is the code I want to use when pressing the toolbar button:
void FPlugiModule::PluginButtonClicked()
{
static ConstructorHelpers::FClassFinder<UEditorUtilityWidgetBlueprint> BBObj(TEXT("/Game/BB"));
if (BBObj.Succeeded()) {
//MenuClass is TSubclassOf<class UEditorUtilityWidgetBlueprint> MenuClass;
MenuClass = BBObj.Class;
}
//Does not work as it can't convert UClass to UEditorUtilityWidgetBlueprint
RunEditorUtilityWidget(MenuClass.Get());
If anyone is still wondering, since it’s hard to find the solution to this. I decided to share what I found.
I found this random chinese website, that posted like just a month ago and it shows a working way to open them via C++:
This is working for a Standalone Window Editor Plugin:
// load UMG Of BP
UBlueprint* UMGBP = LoadObject<UBlueprint>(nullptr, L"/Game/yaksueEditorUtilityWidgetBlueprint"); //Reference to your EditorUtilityWidget
// Modelled on the UEditorUtilityWidgetBlueprint::CreateUtilityWidget() Do it again
TSharedRef<SWidget> TabWidget = SNullWidget::NullWidget;
{
UEditorUtilityWidget* CreatedUMGWidget = nullptr;// Created UMG Control
UClass* BlueprintClass = UMGBP->GeneratedClass;
TSubclassOf<UEditorUtilityWidget> WidgetClass = BlueprintClass;
UWorld* World = GEditor->GetEditorWorldContext().World();
if (World)
{
if (CreatedUMGWidget)
{
CreatedUMGWidget->Rename(nullptr, GetTransientPackage());
}
CreatedUMGWidget = CreateWidget<UEditorUtilityWidget>(World, WidgetClass);
}
if (CreatedUMGWidget)
{
TabWidget = SNew(SVerticalBox)
+ SVerticalBox::Slot()
.HAlign(HAlign_Fill)
[
CreatedUMGWidget->TakeWidget()
];
}
}
Don’t forget to do this: #include “Editor/Blutility/Classes/EditorUtilityWidget.h”
Also add
“UMGEditor”,
“Blutility”,
“UMG”
to your private dependencies in the Build.cs of the plugin.
// Copyright Epic Games, Inc. All Rights Reserved.
#include "bplib.h"
#include "Editor/Blutility/Classes/EditorUtilityWidget.h"
#define LOCTEXT_NAMESPACE "FbplibModule"
void FbplibModule::StartupModule()
{
// This code will execute after your module is loaded into memory; the exact timing is specified in the .uplugin file per-module
}
void FbplibModule::ShutdownModule()
{
// This function may be called during shutdown to clean up your module. For modules that support dynamic reloading,
// we call this function before unloading the module.
}
void FbplibModule::PluginButtonClicked()
{
}
// Modelled on the UEditorUtilityWidgetBlueprint::CreateUtilityWidget() Do it again
TSharedRef FbplibModule::OnSpawnPluginTab(const FSpawnTabArgs& SpawnTabArgs)
{
UBlueprint* UMGBP = LoadObject<UBlueprint>(nullptr, L"/Script/Blutility.EditorUtilityWidgetBlueprint'/bplib/bplib.bplib'"); //Reference to your EditorUtilityWidget
TSharedRef<SWidget> TabWidget = SNullWidget::NullWidget;
{
UEditorUtilityWidget* CreatedUMGWidget = nullptr;// Created UMG Control
UClass* BlueprintClass = UMGBP->GeneratedClass;
TSubclassOf<UEditorUtilityWidget> WidgetClass = BlueprintClass;
UWorld* World = GEditor->GetEditorWorldContext().World();
if (World)
{
if (CreatedUMGWidget)
{
CreatedUMGWidget->Rename(nullptr, GetTransientPackage());
}
CreatedUMGWidget = CreateWidget<UEditorUtilityWidget>(World, WidgetClass);
}
if (CreatedUMGWidget)
{
TabWidget = SNew(SVerticalBox)
+ SVerticalBox::Slot()
.HAlign(HAlign_Fill)
[
CreatedUMGWidget->TakeWidget()
];
}
}
}
#undef LOCTEXT_NAMESPACE
IMPLEMENT_MODULE(FbplibModule, bplib)
header
// Copyright Epic Games, Inc. All Rights Reserved.
#pragma once
#include "CoreMinimal.h"
#include "Modules/ModuleManager.h"
class FbplibModule : public IModuleInterface
{
public:
/** IModuleInterface implementation */
virtual void StartupModule() override;
virtual void ShutdownModule() override;
/** This function will be bound to Command (by default it will bring up plugin window) */
void PluginButtonClicked();
TSharedRef OnSpawnPluginTab();
};
This post was great, but as written can cause crashes when the level changes. So I did it this way calling the UEditorUtilityWidgetBlueprint method rather than rebuilding it: