One of the most common questions you'll have if you start making C++-based UIs is this:
How can I control Blueprint-created widgets from C++?
The answer to this is the
BindWidget meta property.
While it's not mentioned on the
it's one of the most useful tags for you as a UI developer.
As an aside, check out my full UPROPERTY documentation that includes all
BindWidget and others.
By marking a pointer to a widget as
BindWidget, you can create an
identically-named widget in a Blueprint subclass of your C++ class, and at
run-time access it from the C++.
Here's a step-by-step process to getting a test working:
- Create a C++ subclass of
- In it add a member variable that is
UWidget*or a subclass of it (e.g.
- Mark it with
- Run the editor and create a Blueprint subclass of your C++ class.
- Create a widget with the same type and exact name as your member variable.
- You can now access the widget from C++.
If any of these steps don't make sense, check out my introductory series on making UIs with Unreal.
Now compile the C++ and open up your Blueprint subclass of the C++ class where
you added the
ItemTitle property. If you compile your Blueprint, you will be
shown an error if there is no TextBlock widget named
ItemTitle inside your
If we now add a Text widget and change its name to match our C++ file, this compilation error will go away, and when we run the game, the text will be changed to say "Hello world!".
Pros & Cons of using
BindWidget and C++
Why would we want to use
BindWidget and C++ instead of just writing
all our logic in Blueprints?
- Easier to maintain complex logic in C++. No spaghetti-fighting in Blueprints.
- Easier for collaboration, no worries about locking Blueprint assets.
- Requires re-compile to see changes. This time cost can be avoided to some extent by using **Live Coding**.
- Harder for non-programmers to see how data is being populated as the logic is moved from Blueprints to C++.
There are some situations where you may have a base C++ class and many different Blueprint subclasses of it. For example a base button class could have common logic in C++, but you could create many different Blueprint subclasses, one for each visual style. Some visual styles might have icons, others might have text, so it would make sense to make the text and icon image widgets optional.
To make a widget optional use
meta=(BindWidgetOptional). With this there
will be no error shown if the Blueprint class does not have a widget with that
- Compiling a Blueprint without a
BindWidget-marked widget will show an error. However it is still possible to run your game. If you want to avoid crashes in this situation, you will need to check that the variable is not
- Normally when ticking the "Is Variable" flag on a UserWidget would make it
available in the Graph tab of the editor. However, if there is a property
with that name, marked as
BindWidget, the only way to make it accessible in the blueprint is add
- By default, variables defined in a parent C++ class are only shown in the Variables list if "Show Inherited Variables" is checked (see screenshot).
- Widgets marked with
BindWidgetare null in the C++ constructor, they are initialized later on in the lifecycle. If you need to do constructor-like setup use the
- It's also possible to control UMG animations from C++ with
- You can combine this with the
SynchronizePropertiesfunction to create UserWidgets whose appearance updates dynamically in the editor.