Unreal Engine·Programming

Customize your Unreal Class Icons

Use your own icons to customize how Unreal Engine classes look and feel.

What we want

Our goal is to be able to customize the editor class icons so we can have a stylish editor that suits our visual style.

When you work with things you like looking at, the work is better.

How to do it

To be able to customize the editor we will need an editor module. Usually when you create an Unreal C++ project two modules appear a <NameOfYourModule> and a <NameOfYourModule>Editor.

We are going to use this second one.

The setup is not difficult. We will simply add some extra lines on the StartupModule function of this Editor Module to assign our new icons.

The first thing we need are the required include files, they are these ones:

#include "ClassIconFinder.h"
#include "Styling/SlateStyle.h"
#include "Styling/SlateStyleRegistry.h"

After that, we are going to declare a static pointer to the slate style we are going to create on our EditorModule ( there may be a better way to do this, but for now this seems to work )

static inline TSharedPtr StyleSetInstance = nullptr;

Now we are ready to write our code, but our code lines can end up being a little longer I prefer to first declare a helper macro to make our lives easier:

#define SLATE_IMAGE_BRUSH( ImagePath, ImageSize ) new FSlateImageBrush( StyleSetInstance->RootToContentDir( TEXT(ImagePath), TEXT(".png") ), FVector2D(ImageSize, ImageSize ) )

Now we can start writing our code in the StartupModule function. First we are gonna create the new SlateStyleSet, we will continue by defining where our icons are going to be located, then we will set values on this StyleSet for our new icons and finally we are going to register the Slate StyleSet:

// Create the new style set
StyleSetInstance = MakeShareable(new FSlateStyleSet("QuodGameplayFrameworkEditorStyle"));

// Assign the content root of this style set
StyleSetInstance->SetContentRoot(FPaths::ProjectContentDir() / TEXT("Editor/Slate"));

// Modify the class icons to use our new awesome icons
StyleSetInstance->Set("ClassIcon.QuodAbilitySystemComponent", SLATE_IMAGE_BRUSH("/Icons/QuodAbilitySystemComponent", 20.0f));
StyleSetInstance->Set("ClassIcon.QuodCharacterDataComponent", SLATE_IMAGE_BRUSH("/Icons/QuodCharacterDataComponent", 20.0f));
StyleSetInstance->Set("ClassIcon.CatSoulsCharacter", SLATE_IMAGE_BRUSH("/Icons/CatSoulsCharacter", 20.0f));
StyleSetInstance->Set("ClassIcon.QuodEquipmentComponent", SLATE_IMAGE_BRUSH("/Icons/QuodEquipmentComponent", 20.0f));

// Finally register the style set so it is actually used
FSlateStyleRegistry::RegisterSlateStyle(*StyleSetInstance);

We will be missing the module shutdown to clean up the StyleSet, you will be able to find it in the full code example at the end of this post.

And by the way, how it is setup right now our icons are expected to live inside Content/Editor/Slate, but you can modify that with the line SetContentRoot

Results

With that we can finally have the results we want with our unreal class icons being customized!

Customized Icons, yay!

Now its up to you to modify everything in Unreal to use your custom icons.

In theory this same method can be used to modify other Slate images inside Unreal, so feel free to experiment.

As an addendum, here is the full code of the Editor Module to make things easier to follow:

#include "QuodGameplayFrameworkEditor.h"
#include "Modules/ModuleManager.h"
#include "Modules/ModuleInterface.h"
#include "Editor/UnrealEdEngine.h"
#include "ClassIconFinder.h"
#include "Styling/SlateStyle.h"
#include "Styling/SlateStyleRegistry.h"

#define LOCTEXT_NAMESPACE "QuodGameplayFrameworkEditor"
DEFINE_LOG_CATEGORY(LogQuodGameplayFrameworkEditor);

#define SLATE_IMAGE_BRUSH( ImagePath, ImageSize ) new FSlateImageBrush( StyleSetInstance->RootToContentDir( TEXT(ImagePath), TEXT(".png") ), FVector2D(ImageSize, ImageSize ) )

/**
 * Gameplay Framework Editor Module
 */
class FQuodGameplayFrameworkEditorModule : public FDefaultGameModuleImpl
{
	typedef FQuodGameplayFrameworkEditorModule ThisClass;

	static inline TSharedPtr StyleSetInstance = nullptr;
	
	virtual void StartupModule() override
	{
		// Create the new style set
		StyleSetInstance = MakeShareable(new FSlateStyleSet("QuodGameplayFrameworkEditorStyle"));
		// Assign the content root of this style set
		StyleSetInstance->SetContentRoot(FPaths::ProjectContentDir() / TEXT("Editor/Slate"));
		// Modify the class icons to use our new awesome icons
		StyleSetInstance->Set("ClassIcon.QuodAbilitySystemComponent", SLATE_IMAGE_BRUSH("/Icons/QuodAbilitySystemComponent", 20.0f));
		StyleSetInstance->Set("ClassIcon.QuodCharacterDataComponent", SLATE_IMAGE_BRUSH("/Icons/QuodCharacterDataComponent", 20.0f));
		StyleSetInstance->Set("ClassIcon.CatSoulsCharacter", SLATE_IMAGE_BRUSH("/Icons/CatSoulsCharacter", 20.0f));
		StyleSetInstance->Set("ClassIcon.QuodEquipmentComponent", SLATE_IMAGE_BRUSH("/Icons/QuodEquipmentComponent", 20.0f));
		// Finally register the style set so it is actually used
		FSlateStyleRegistry::RegisterSlateStyle(*StyleSetInstance);
	}

	virtual void ShutdownModule() override
	{
		FModuleManager::Get().OnModulesChanged().RemoveAll(this);

		// Unregister the style set and reset the pointer
		FSlateStyleRegistry::UnRegisterSlateStyle(*StyleSetInstance.Get());
		StyleSetInstance.Reset();
	}
};

IMPLEMENT_MODULE(FQuodGameplayFrameworkEditorModule, QuodGameplayFrameworkEditor);

#undef LOCTEXT_NAMESPACE

Recap

  • The work lives in your Editor module’s StartupModule: create an FSlateStyleSet, point its content root at where the icons live ( Content/Editor/Slate here, via SetContentRoot ), Set an entry for each icon, then register it with FSlateStyleRegistry::RegisterSlateStyle. ShutdownModule unregisters it and resets the pointer.
  • The key string is what binds an image to a class. “ClassIcon.QuodEquipmentComponent” maps that icon onto the QuodEquipmentComponent class, so the prefix and the class name have to match exactly.
  • Keeping this in the Editor module means it doesn’t ship in the cooked game, and it’s a one-time registration at editor startup.

What this doesn’t cover

This changes the class icon, the small icon shown for a class or component, not the asset thumbnail the content browser renders for actual assets. Thumbnails go through Unreal’s thumbnail renderer system, which is separate from Slate style sets. I only showed the editor-module route here, not a plugin-based one. And as the code notes, the static-pointer setup is what worked for me, not necessarily the cleanest way to hold the style set.

Keep reading

GiveAbilityAndActivateOnce: One-Shot Abilities Without the Cleanup

GiveAbilityAndActivateOnce: One-Shot Abilities Without the Cleanup

Grant an ability, activate it once, and let GAS remove the spec by itself.
How to Create Procedural Levels with Level Instances in UE5

How to Create Procedural Levels with Level Instances in UE5

Create the Procedural World of your Dreams
Learning about Ability Instancing Policy in GAS

Learning about Ability Instancing Policy in GAS

So many instancing types!