In the last article, we introduced the UMG Editor Widgets which allows you to define editor widgets using the UMG designer since Unreal Engine 4.22.

In this article, we cover the usage of UMG Editor Widgets, but using C++. Of course, it was already possible to define editor widgets using C++ before the 4.22, but this new release added new possibilities. We can now, for instance, define an Editor Widget class from C++ and extend it using an Editor Utility Widget Blueprint. This allows us to eventually benefits from C++ functionnalities while using the UMG designer.

EditorUtilityWidget class and plugin creation

If we let our cursor over the Editor Widget we created the last time, we can notice that the parent class of the asset is the EditorUtilityWidget class. This class will be our base class to define an Editor Widget from C++. The problem is that there is not yet a lot of resource explaining how to interact with this class, so it may require a bit of reverse engineering to understand how to use its functionnalities.
The official documentation can be found here. To look for the source code of the class, or the exposed functions, we can go to the folder Editor/Blutility of the engine sources.

But to start, we will need to create a Plugin. Indeed, the EditorUtilityWidget functionnality is editor only so it must be in an « Editor » plugin.
To do this, we will go in Settings > Plugins and will click on New Plugin… There we can choose a blank plugin. We will just need to edit the uplugin file and set the type of the module to « Editor » instead of « Runtime », and in the .build.cs file we will add « UnrealEd », « UMG », and « Blutility » to the list PrivateDependencyModuleNames.

Just in case, you can also read the following tutorial on Epic’s wiki: https://wiki.unrealengine.com/Creating_an_Editor_Module.

In my case, I created a plugin named CppEditorWidget and I have the following files.

For the .uplugin:


{
	"FileVersion": 3,
	"Version": 1,
	"VersionName": "1.0",
	"FriendlyName": "CppEditorWidget",
	"Description": "",
	"Category": "Other",
	"CreatedBy": "",
	"CreatedByURL": "",
	"DocsURL": "",
	"MarketplaceURL": "",
	"SupportURL": "",
	"CanContainContent": true,
	"IsBetaVersion": false,
	"Installed": false,
	"Modules": [
	{
		"Name": "CppEditorWidget",
		"Type": "Editor",
		"LoadingPhase": "PostEngineInit"
	}
	]
}

For the .build.cs:

using UnrealBuildTool;

public class CppEditorWidget : ModuleRules
{
	public CppEditorWidget(ReadOnlyTargetRules Target) : base(Target)
	{
		PCHUsage = ModuleRules.PCHUsageMode.UseExplicitOrSharedPCHs;
		
		PublicIncludePaths.AddRange(
			new string[] {
				// ... add public include paths required here ...
			}
			);
				
		
		PrivateIncludePaths.AddRange(
			new string[] {
				// ... add other private include paths required here ...
			}
			);
			
		
		PublicDependencyModuleNames.AddRange(
			new string[]
			{
				"Core",
				// ... add other public dependencies that you statically link with here ...
			}
			);
			
		
		PrivateDependencyModuleNames.AddRange(
			new string[]
			{
				"CoreUObject",
				"Engine",
				"Slate",
				"SlateCore",
                "UnrealEd",
                "Blutility",
                "UMG"
				// ... add private dependencies that you statically link with here ...	
			}
			);
		
		
		DynamicallyLoadedModuleNames.AddRange(
			new string[]
			{
				// ... add any modules that your module loads dynamically here ...
			}
			);
	}
}

The C++ code of the class

As said before, we need to extends the EditorUtilityWidget class. This is what we can have/

MyEditorWidgetClass.h:


#pragma once

#include "CoreMinimal.h"
#include "Editor/Blutility/Classes/EditorUtilityWidget.h"

#include "MyEditorWidgetClass.generated.h"

/**
 * 
 */
UCLASS(BlueprintType)
class CPPEDITORWIDGET_API UMyEditorWidgetClass : public UEditorUtilityWidget
{
	GENERATED_BODY()

public:
	UMyEditorWidgetClass();
	~UMyEditorWidgetClass();

	UFUNCTION(BlueprintCallable)
		void Hello();
};


MyEditorWidgetClass.cpp:


#include "MyEditorWidgetClass.h"

#define DEBUG_MSG(x, ...) if(GEngine){GEngine->AddOnScreenDebugMessage(-1, 15.0f, FColor::Red, FString::Printf(TEXT(x), __VA_ARGS__));}

UMyEditorWidgetClass::UMyEditorWidgetClass()
{
}

UMyEditorWidgetClass::~UMyEditorWidgetClass()
{
}

void UMyEditorWidgetClass::Hello()
{
	DEBUG_MSG("Hello")
}

Here, we are just creating a class with a function which prints « Hello » on the screen as a debug message. But we could override the constructor, or add more complex functions.

In case you add difficulties following the current tutorial, the whole plugin can be downloaded here:

CppEditorWidget

Just create the « Plugins » folder in your project folder and unzip the content of the archive there.

Using the newly created class

We will start by creating a new Editor Widget Utility Blueprint, like we did in the first tutorial, then we open it.
After, we go in the Event Graph so we can edit the class settings and change the parent class. By setting our C++ class as the parent class, we are now able to call the C++ functions defined in the C++ class.

Conclusion

Obviously, this example is quite simple: we are not really using the full potential of the C++ functionnalities, however we are presenting how we could do it. If you are familiar with UE4 C++ you should now be able to see how C++ functions can be called from the Editor Widget. In the next article, we will see more details about it, and we will focus on how we can edit and control the widget from the C++. If you want to be notified when the next articles will be published, you can follow us on Twitter and Facebook.