Download

Can't make C++ communicate with Widget Blueprint!

I have a Widget Blueprint which has to appear on the screen in some circumstances.

ccc.jpg

Now the problem is: how do I access the Widget (and so, its variables) in my C++ code?

I already read this tutorial

But the problem is that I have a **UserWidget pointer, **and this means I can’t access the Widget Blueprint variables

What I need is a **reference to the ****instance of the Widget Blueprint **in my C++ code, so that I can access its variables/functions.

I have to, in some way, link the Blueprint class to C++

------------------- my (failed) attempt -------------------

I already tried making a GameMode Blueprint like this

I saved the reference in the GameMode because **I always need that reference, even when the Level changes: it’s a “game constant”

But the problem arises again**

I need a way to link the GameMode Blueprint to C++ in order to use that reference

It’s always the same story.

**What can I do? **
Thanks in advance

There are ways to access Blueprint variables in C++ but it’s not pretty and normally not recommended.

If you know this widget will have these variables, you’re better off just creating a new Widget (UMyProgressBarWidget) that inherits from UUserWidget and has those as simple C++ UPROPERTIES with BlueprintReadWrite so they can be accessed via Blueprints as well.

The related UE4 Wiki Tutorials to do what @ExtraLifeMatt is so correctly saying are here:

Referencing UMG Widgets in C++
https://wiki.unrealengine.com/UMG,_R…idgets_in_Code

UMG, How to extend a UUserWidget:: for UMG in C++
https://wiki.unrealengine.com/UMG,_H…UMG_in_C%2B%2B.

:slight_smile:

Rama

The best practice is to make a base C++ user widget class that contains all the things that you need to access from c++ and then make your umg blueprint inherit from that class.

Hello gedamial,

My advice for you is: make as much as you can in C++. It seems to be more work, but, in the end, it’s easier to maintain and do what you need.

If it help you, a few steps I’d recommend you doing.

  1. Start by creating a [FONT=courier new]MyGameBaseWidget class (sample name, ofc), which inherits from [FONT=courier new]UUserWidget. If you have function/variables common to all the widgets you’re going to create, you’re free to add them here.
  2. Create a [FONT=courier new]UCircleProgressBaseWidget[FONT=courier new] which inherits from [FONT=courier new]MyGameBaseWidget
  3. Create component pointers at c++ level (while this is optional and used for optimization, it’s a good idea to have these) for stuff you will need to access directly from the code. I.e.: [FONT=courier new]UEditableTextBox* EditableBoxPtr;
  4. Tied with step 3 (so, if you skipped it, you won’t need this function, but will need to understand how it works), you need to get the custom component from the blueprint, so do this:
    (Remember to set it to [FONT=courier new]nullptr in the constructor too!)
UEditableTextBox* UCircleProgressBaseWidget::GetEditableBox()
{
    if (EditableBoxPtr)
        return EditableBoxPtr;

    const FName EditableBoxName = FName(TEXT("YourCustomComponentNameInBPGoesHere"));
    EditableBoxPtr = (UEditableTextBox*)(WidgetTree->FindWidget(EditableBoxName));

    return EditableBoxPtr;
}

If you have a child blueprint in this blueprint, you can refer it to as [FONT=courier new]UUserWidget*

  1. Edit the target data. Of course, C++ only recognizes the basic elements defined in code, such as [FONT=courier new]UEditableTextBox in the example above.

This is one way of doing it. There’s ways to call a BP only function too, but it’s kinda slow…
If I had to call a BP function, I’d do it either as BlueprintCallable, to define it in C++ and use as much C++ as possible (while harder to do, it’s easier to maintain, IMO) or some other UFUNCTION flag that helps me in the process. Looking up names in BP is expensive and should be avoided as much as possible (hence, that strategy of steps 3 and 4 of having a pointer cache!)

I hope that helps! Post back with your results if you can, please :slight_smile:

You don’t need to do any of the above anymore, you can just create a pointer to the type in the header, and the engine will link it up automatically:



UPROPERTY(meta = (BindWidget))
UEditableTextBox* MyTextBox;


Now simply create a Widget Blueprint that inherits from your C++ class and add an Editable Text Box called ‘My Text Box’.

Its actually not that hard once you get used to it. So first, make a C++ class inheriting from UUserWidget. Then make the blueprint inherit from the C++ class you just created. Now for a simple button, just do this.

example:
in the header



UPROPERTY(meta = (BindWidget))
        class UButton *MyCoolButton;

protected:
    virtual bool Initialize() override; // override this, its like beginplay but for UUserWidgets


in the .cpp



#include "Components/Button.h"

bool UWidgetClassName::Initialize()
{
    bool Success = Super::Initialize();
    if (!Success) return false;

    if (!ensure(MyCoolButton)) { return false; } // check for nullptrs
    MyCoolButton->OnClicked.AddDynamic(this, &UWidgetClassName::DoAction);

    return true;
}

void UWidgetClassName::DoAction()
{
    GEngine->AddOnScreenDebugMessage(-1, 5.0f, FColor::Yellow, TEXT("Hello World"));
}


Now make the widget component in the BP with the exact same name as in C++ (so in the above example, name it MyCoolButton). Then everything should work. Your widget designs can be in BP but the logic for them is in C++.