Why are both the slot and GetRootWidget() in UUserWidget always nullptr?

When I try to retrieve the root widget in a UUserWidget it is always nullptr.

if (!Cast<UPanelWidget>(GetRootWidget())) {
		GEngine->AddOnScreenDebugMessage(-1, 3.0f, FColor::Red, "omfg");
	}

Similarly when I try to retrieve the slot of the root widget it always returns nullptr.

if (!Cast<UPanelWidget>(GetRootWidget())->Slot) {
		GEngine->AddOnScreenDebugMessage(-1, 3.0f, FColor::Red, "ugh");
	}

I first tried to create my widget by making the main canvas:

newCanvas = Cast<UCanvasPanel>(GetRootWidget());

But obviously that doesn’t work because GetRootWidget() is nullptr. So then I tried:

newCanvas = WidgetTree->ConstructWidget<UCanvasPanel>(UCanvasPanel::StaticClass());

WidgetTree->RootWidget = newCanvas;

newCanvas->Slot = NewObject<UPanelSlot>();

UCanvasPanelSlot* baseSlot = Cast<UCanvasPanelSlot>(newCanvas->Slot);
baseSlot->SetSize(FVector2D(500.0f, 500.0f));

But obviously that gave me a read access violation because the slot isn’t actually a part of a widget, and it can’t be because the root widget is * nullptr.

I see “omfg” and “ugh” on screen and that’s how I feel. How are you supposed to build a UUserWidget in c++ if you can’t even place widget objects in the widget?

The short answer is that you aren’t supposed to. UMG widgets are meant to be assembled in the UMG designer, then you can spawn those widgets from code. There is an awful lot of additional generation that goes on behind the scenes when you compile widgets in the editor.

There are mechanisms in place to allow you to specify optional/required sub-widgets and animations that C++ can reference, such as:

BindWidget
BindWidgetOptional
BindWidgetAnim
BindWidgetAnimOptional
IsBindableEvent

etc.

See the Widget.h header - or look at the more recent sample projects.

Okay so then what would you suggest I do if I’m spawning in a c++ based actor with a widget component? When I spawn them in, all of the widget components get spawned with attachments to the same widget so all of the spawned actors have the exact same healthbar & data. How do I get around this? I know this is considered another question so I can make that as well but I was hoping you could answer here since you’re all filled in and everything.