In the previous tutorial we showed how you can create a UserWidget Blueprint in the editor, and then why it's a good idea to transition to a mix of C++ and Blueprints in our UI.
In this approach we will create a new C++-based subclass of
UUserWidget, and then create a Blueprint subclass of that new C++ class.
Example UUserWidget Subclass
This sample is the most basic, empty "hello world" example User Widget we can create. We will add functionality to it later.
Now that you have a basic example, compile and run the editor.
We now want to create a UserWidget Blueprint class that is a subclass of our newly-created C++ class. There are two ways to do this:
- Either we create a brand-new UserWidget
- Or we change the parent of an existing UserWidget.
Creating a new Blueprint subclass of our C++ Class
When creating a new UserWidget, instead of using the right-click "create UserWidget" shortcut, you need to use the more general "create Blueprint shortcut. Then from the list choose your newly created
ExampleWidget as the base class.
Note: The industry-standard style guide for Unreal Engine recommends prefixing User Widget Blueprints with
WBP_. I also personally like prefixing C++ UserWidget subclasses with
Changing the parent class of an existing Blueprint
Alternatively, we can change the parent of an existing UserWidget Blueprint. Open your Blueprint, then from the menu at the top chooose
File > Reparent Blueprint. In the popup window choose your
You can see the Blueprint UserWidget's parent class in the top-right of the editor window. If it says ExampleWidget, you're good to go!
Now we Have a C++ Base Class, What Next?
Now your Blueprint Widget has a custom parent C++ class, we will have the benefits mentioned in the previous tutorial, and also:
Blueprints or C++?
After working with UMG for a year, I can safely say one of the most tricky things to decide when you're making a game's UI, is how to mix C++ and Blueprints in the UI.
A game's UI is usually one of the most frequently changed parts of the game. Prototypes and mock-ups are created and thrown away almost every month, and often it is quicker to start from scratch every time.
At first, it would seem natural to use only Blueprints for your UIs. They're much quicker to create and test, especially if your C++ build times are particularly long.
However I found that every time I had to create a new iteration of the UI, with a new organization of widgets, I often had to rewrite significant chunks of Blueprint logic. I improved the situation somewhat by creating reusable utility classes in Blueprints, but it was still impossible to inspect data for most variable types in Blueprints.
There is a better compromise, that works quite well in my experience. It is better to put all the data-related logic in C++, and the visual logic in Blueprints.
Generally the data changes much less frequently than the UI visuals, and when refactoring systems it becomes clear how your UI struct-populating C++ code needs to be refactored. Then in the Blueprint, it is a simple matter of connecting up the struct properties to the widgets that use them.
Imagine we wanted to populate a very specific widget with a plant's name and its icon. If the player had not discovered the plant yet, those could be replaced in the C++ with correct "unknown plant" values.
The next tutorial in the series covers creating a C++ subclass of
UWidget, which will give us the ability to make generic reusable components that do not rely on Blueprint subclasses.