How do i go from SWidget to UWidget ?

Hey everyone !

I have a fairly complex UI made with slate in c++, using lots of SWidgets.

I would like to make it 3D, so (if i understood correctly), i need to translate my SWidgets to UUserWidgets.

So i have created a class inheriting from UUserWidget but i don’t know where to go from here.

All the variables/functions concerning swidget (MyWidget, BuildDesignTimeWidget…) seem to be protected.

Following this post:

It seems that i just have to “wrap” the SWidget in UWidget, but i don’t know how to do that.

Can someone point me in the right direction ?

Thanks

Cedric

You should inherit from UWidget, not UUserWidget. UUserWidget is a special classification of widget that are designed to be inherited by the designer. If you’ve already got an entire UI (or large complex pieces) and you just want to build a wrapper for it that lets someone configure some stuff about it, UWidget is the way to go.

You should take a look at any of the UWidgets in the UMG module on github NativeWidgetHost is probably a good one to use as a reference; it’s pretty minimal.

Hi Nick,

Thanks a lot for the pointer, in fact, NativeWidgetHost looks like what i want, so no need to rewrite it.

So i added this to my code (character class):

UPROPERTY(VisibleAnywhere, BlueprintReadWrite, Category = YagUI)
	UNativeWidgetHost* ThisNativeWidgetHost;
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = YagUI)
	UWidgetComponent* ThisWidgetComponent;

---------------------------------------------------------

ThisNativeWidgetHost = ObjectInitializer.CreateDefaultSubobject<UNativeWidgetHost>(this, TEXT("native widget host"));
ThisWidgetComponent = ObjectInitializer.CreateDefaultSubobject<UWidgetComponent>(this, TEXT("widget component"));
ThisWidgetComponent->AttachParent = RootComponent;

The component now appears in my character BP list of components, but i can’t find a way to define the widget class in c++.

In the doc i found a GetWidgetClass function, but no SetWidgetClass() nor SetWidget() nor GetUI() functions.

How do i assign the ThisNativeWidgetHost object to the ThisWidgetComponent component ?

Thanks

Cedric

Hey Nick,

I have tried this in the PostInitializeComponents() function of my actor:

	if (GetWorld()->GetFirstPlayerController())
	{
		AYagHUD* YagHUD = Cast<AYagHUD>(GetWorld()->GetFirstPlayerController()->GetHUD());
		if (!YagHUD) return;

		GEngine->AddOnScreenDebugMessage(-1, 10.f, FColor::Red, TEXT("hud ok, adding widget"));

		// set the widget
		ThisNativeWidgetHost->SetContent(YagHUD->YagHUDWidget.ToSharedRef());
	}

I get the “hud ok” message, but the widget is not displayed and the WidgetCompoennt remains invisible (although i checked “opaque” and “twosided” in the editor)

YagHUDWidget is my mother widget, a large SCompoundWidget containing a ton of children.

If i manually assign a class to the component (from the editor), i can see it in game, so there is something wrong in my above code.

Or maybe shouldn’t it be in the PostInitializeComponents() ?

I’m going on with my tests, and will update if i find something, but any hint would be great.

Cheers

Cedric

Hey Nick,

I’m really lost here.

I debugged my code and found that my UNativeWidgetHost was correctly containing my SCompounWidget, so it seems that i successfully created and populated a UNativeWidgetHost, all good.

But my UWidgetComponent has both its Widget and SlateWidget variables set to null.

In fact i realized that i had not assigned the native widget host to the widget component. No wonder it didn’t work !!

So i tried this promising direction but nowhere could i find a SetWidget() function in the widget component doc.

So i went into the code and i couldn’t find such a function in the public section. Moreover, the Widget variable is private, so i can’t see a way to assign a UWidget to a UWidgetComponent.

Going into the UE code i brand new to me, my skills are quite limited so maybe i missed something obvious ?

Currently, both roads to success seem closed:

  • i can’t have my SCompoundWidget appear in the UMG list so i can’t assign it to a native host widget in the UMG editor

  • i can’t assign my c++ created UNativeHostWidget to a UWidgetComponent

Cedric

Hey Nick,

Ok, some progress.

I watched the UEditableText code and understood i had to overwrite RebuildWidget so i copy pasted the native widget host into a class inheriting from UWidget (UYag3DWidget here) and changed this:

TSharedRef<SWidget> UYag3DWidget::RebuildWidget()
{
	return SNew(SYagHUDWidget);
	//return BuildDesignTimeWidget(MyWidget.ToSharedRef());
}

Using BuildDesignTimeWidget gives a crash, but returning just SNew() is ok.

My Yag3DWidget class is now visible in the umg designer list and i can now see it ingame.

But i am now facing 2 other problems:

  • i had to cut all initializations, so the 3D UI is all empty (i need ingame infos to initialize it properly). So i need to find a way to force the proper reconstruction in game.

  • it doesn’t respond to mouse. I have followed the “create 3D widget” tutorial in the doc, but with the same settings i couldn’t have my widget actor respond to mouse yet.

Continuing the tests.

Cedric

Hey,

I have followed the 3D widget tutorial and ended up with a strange behavior.

https://docs.unrealengine.com/latest/INT/Engine/UMG/HowTo/Create3DWidgets/index.html

The only button responding to hovering and clicking is the top one, but it responds when i hover/click the half right part of the bottom button.

Here is a picture: the area surrounded by red is the response area for the top button.

It follows very precisely the boundary of the bottom button (half of it)

Cedric

Finally found a solution, i posted it both on the other thread i created here and on the forum:

And for reference:

Cheers

Cedric