I had problems with C++ properties set from blueprints in a project I took over from a colleague, so I created an empty project to reproduce.
I created an empty project with the Games/Blank template in Unreal 5.6.1, Blueprint type. Then I added C++ class to make it a hybrid project. I named the class MyUserWidget and had it inherit from UserWidget. The header looks like this:
#pragma once
#include "CoreMinimal.h"
#include "Blueprint/UserWidget.h"
#include "Components/TextBlock.h"
#include "MyUserWidget.generated.h"
/**
*
*/
UCLASS()
class WIDGETPROPERTYTEST_API UMyUserWidget : public UUserWidget
{
GENERATED_BODY()
public:
UPROPERTY(BlueprintReadWrite, EditAnywhere)
UTextBlock* Schrott;
void DoSomething();
};
Then I created a new blueprint based on my class MyUserWidget. I added a TextBlock (Common/Text, class UTextBlock) to it. I do not check the “Is Variable” in the TextBlock and I do not change any properties of the TextBlock. As expected, the blueprint has a property called Schrott that I can set to the newly added TextBlock. When I compile the blueprint, the property gets reset to empty.
Now as far as I know this is the only way to access elements created in the blueprint designer from C++ code, so how am I supposed to access those elements now?
I found these related forum entries, but they did not help me:
As suggested in one of the posts, I tried deleting the TextBlock and re-adding it. After doing so, Unreal no longer suggests the TextBlock as possible value in the dropdown of my Schrott property, but I have no idea why.
I also tried creating the project as C++ type, which did not help.
I also tried the same process with Unreal 5.7.3, which did not help.
You assign the property reference to you base class and you expect it to be referenced however designer created widgets don’t work like that.
Designer created widgets, are recreated / assigned on compile, preview so your assignment will fall.
The proper approach is slightly different.
If you want to access a TextBlock created in the designer from C++, use UPROPERTY(meta=(BindWidget)) and mark the TextBlock as “Is Variable” in the Blueprint. The names must match.
However I don’t like this approach to be honest what I do is actually even more different, I prefer manual lookups generally.
void UMyUserWidget::NativeConstruct()
{
Super::NativeConstruct();
// We simply search by string when hit do something.
if (WidgetTree)
{
UWidget* Found = WidgetTree->FindWidget(TEXT("Schrott"));
Schrott = Cast<UTextBlock>(Found);
}
}
This way I can control the lookup and assignment at runtime for various situations.
You are looking for the BindWidget meta tag, I think?
UPROPERTY(meta = (BindWidget))
class UTextBlock* Schrott;
This lets you add UMG widgets and bind them so you can use them in c++. The widget must have the EXACT same name you give it in c++. There is a Bind Widgets panel in the Widget Designer view that shows the status of your widget bindings.