Blueprint Data Types Problem

I’ve read several posts in Forum and AnswerHub about primitive data type support in Blueprint. One of them is this link:

The problem is, there are some things that even C++ cannot fully control everything in the game and force developers to include Blueprint in it. One such example is controlling and modifying UMG via C++. It is somehow impossible to fully create/construct a Widget (in C++) without any reference to a Widget Blueprint. The constructors force us to have a Widget Blueprint. If I want to have 64-bit data types (int64 or double) in my Widget (in C++), which can be edited anywhere, then it will not be possible because the Widget Blueprint does not support 64-bit data types.

Many sources, I saw, suggest to use Slate framework for C++. But Slate framework is just too complicated. Why not just use simple function calls in ordinary C++ to modify UMG, as it is done in Blueprint? So this condition is extremely annoying.

If UE does not want Blueprint to support 64-bit data types, then at least provide a mechanism in which C++ coders can create/construct anything (such as Widgets) without any reference to a Blueprint. In fact, I just hope that the entire game, no matter how complicated, can be created by using pure C++ and zero Blueprints.

So UE management, please make the right decision because your current decision to exclude 64-bit data types in Blueprint, while forcing developers to always include Blueprint, is terrible. You obstruct the full potential of a game engine. And UE should actually be one of the best ones in the market.

First, this isn’t a bug. Adding a native data type to blueprints is way more complicated than typing a single line of code. They kept uint8, float, and int32 from UnrealScript.

Second, UUserWidgets in C++ do not require a widget blueprint at all, allowing you to use any data type. You extend UUserWidget and override NativeConstruct for the constructor. It takes no arguments. From that class you can add all of the widgets such as UButton (UButton::OnClicked.AddDynamic()) and other similar elements. After that you simply add a NewWidget call and pass in your class, then you AddToViewport from your PlayerController.

Don’t call something a bug just because you don’t know how to use it.

Okay genius! How do I override the NativeConstruct() function? What should I fill in it?

Adding UButton and other elements is easy in the header file. But how do you exactly instantiate it without referring to any Widget Blueprint?

In what class is this “NewWidget” function located? It does not exist in UUserWidget class.

How do you exactly do “pass in your class” ?

In short, show me the exact source code that you have in mind and prove me wrong!

For some reason the comment box above isn’t taking too kindly to my response.

First you create a widget that extends UUserWidget.

class UMyUserWidget : public UUserWidget

Next you override the NativeConstruct method.

virtual void NativeConstruct() override;

In your .cpp file you implement NativeConstruct.

void UMyUserWidget::NativeConstruct()
{
    Super::NativeConstruct();

    // Bind delegates here.
}

In your PlayerController class create and display the widget.

UserInterface = CreateWidget<UMyUserWidget>(this, UMyUserWidget::StaticClass());
FInputModeGameAndUI Mode;
Mode.SetLockMouseToViewport(true);
Mode.SetHideCursorDuringCapture(false);
SetInputMode(Mode);
UserInterface->AddToViewport(9999); // Z-order, this just makes it render on the very top.

Now that you have created your base widget in C++ you can start adding components to it. It is extremely important to note that widget components are also widgets. This means you create them in the exact same way you create your UUserWidget.

In your header file define a widget type. In this case I’ll define a UButton.

UPROPERTY()
UButton* ExampleButton;

In your CPP file you will instantiate that button.

UPanelWidget* RootWidget = Cast<UPanelWidget>(GetRootWidget());

ExampleButton = WidgetTree->ConstructWidget<UButton>(UButton::StaticClass(), TEXT("MyButtonName")); // The second parameter is the name and is optional.
ExampleButton->OnClicked.AddDynamic(this, &MyUserWidget::OnButtonClicked); // Example click binding.
RootWidget->AddChild(ExampleButton);

There are, of course, more steps in this like setting the padding, color, and other properties. It is best that you give your widgets names so you can find them later using using WidgetTree->FindWidget(TEXT(“WIDGET_NAME”)).

Somehow it’s easier said than done. Where do you create this UButton? Inside NativeConstruct() function inside UMyUserWidget?

GetRootWidget() always return NULL. Hence an error occur during runtime.

You would likely do this in RebuildWidget. Admittedly I have not reached this point in my own project yet (since GUI is last on my list).

Somehow every answer lead to more questions. That function must return a value. What value should it return? Is null allowed?

Anyway, thank you for being honest about this. So seems like you cannot prove me wrong after all. So my question/complain still stand.

I am hoping for a valid answer from UE developer team about this condition. Is it true that a simple widget (with 1 UTextBlock in it) cannot be purely created in C++ (without any reference to widget blueprint) ?

Because I’ve read many other posts on this topic and many say that’s impossible. UMG must include blueprints (pure C++ is not allowed). Even though I tried many thing to get it working in pure C++, it does not show in the screen when I play it with PIE.

Is it supposed to be possible? If yes, then why is the widget not showing? Is it a bug in UE?

The return value of RebuildWidget is Super::RebuildWidget.

TSharedRef<SWidget> UMyWidget::RebuildWidget()
{
    TSharedRef<SWidget> Widget = Super::RebuildWidget();

    ...

    return Widget;
}

It seems like 64-bit primitive data type support will be ignored for years to come. It’s a pity. If UE could support it, then UE will be the best game engine for many years to come.