Get root widget of UMG in blueprints?

I’d like to get the very first element placed in User Widget. When I get it, I can search children (all included widgets) fully dynamically. Is it possible to get this root in blueprints?

AFAIK I could achieve it in C++ by calling GetRootWidget(), right?
But I’m preparing blueprint only package in order to give it to community. I’d have to create code plugin for one function call if there’s no way to get this information in blueprints :wink:

Yes it is with a little workaround.

I create a sample widget with the following structure:

98934-widget1.jpg

It has a root component (which you want to access) and 4 childrens.
Then click the root component and check the “Is Variable” checkbox in its details panel.

98937-widget2.jpg

Now go to the widgets graph tab and the root component is accessible as a variable and can used as you wish:

98940-widget3.jpg

Yes, it would work if I’d apply script in every asset :slight_smile:
But I’m looking for way to get root without referencing to any specific variable, just get it dynamically.
Let’s say I got PanelBase and every other panel is child of it. I call “Get Root Widget” only in PanelBase without knowing what’s inside of children.
Well… it looks like I need to put C++ function into plugin.

Still, thanks for help! :slight_smile:

I think then c++ is the only way. Have a nice day!

Here is what I did (Blueprints!)

1.Create a Blank UserWidget named Menu_Base

2.Open Menu_Base and in designer delete the default CanvasPanel_0 (errors and warnings if you dont!)

3.Open Graph and create a variable called Root_Panel_Widget of “Panel Widget” type
Make sure to set this as VISABLE (The little eye needs to be Yellow)
(Panel Widget is the base class for all containers that can have children!! i.e canvas,border, grid ect)

4.Compile and save and close this, we are done here.

Now for some reason you cant right click and use “Create Child” on Menu_Base, so:

5.Create a Blank UserWidget and open (or use an existing UserWidget you’d like to remap)

6.Click on the FIRST Child in designer and select IS VARIABLE to True (CanvasPanel_0 in a new widget)

7.Open Class Settings, and change the parent class to Menu_Base
8.In this widget get your Event Construct, and set Panel_Widget_Root as CanvasPanel_0

9.Compile and save.

Now you can use Panel_Widget_Root at runtime and call Get Children!!!

Here is my fancy function (has to be a function, do not use as an event! (breaks the loops) that changes ALL buttons and checkboxes for a uniform appearance across the whole game, this also allows the user to choose pre-selected images for personalizing their own preferences!
I have a Widget that has a SwitcherWidget that contains ALL menu/settings/lobby/char selection ect widgets
Some of the sub Widgets also have SwitcherWidgets!

Here is the result!
The Back/Quit buttons are default, the rest are changed at runtime!
If I want to change the appearance, I make ONE function call on the root UserWidget and done!

The beauty with UE4 is the Parent/Child Object Oriented system. If you just know how to create the container in BP, you can get around almost all missing Parent/Child functionality.
Look at my answer below for my answer/example.

I used a similar parent/child “container” system to map “modules” to meshes on my character (to extend Mesh functionality, such as armor, damage, cooling system) by attaching “child actors” to each mesh and setting them at runtime.

p.s created in 4.18
Not sure when this changed, but as of 4.20/21 you have to add “Add Call to Parent” on the “Event Construct” of each child or this wont work (you add this call after the childs event construct

OR
In the children, move the set panel root to the PRE construct part, and make sure you delete the empty Event Construct (or add the parent call if you have other code here)

For anyone in need of the “Get Root Widget” function in blueprints, especially in the dynamic widget tree where assigning manually isn’t practical, here’s a recursive function inspired by “BDC_Patrick :de::uk::us:” from the Discord community.
I have tested it. Started from Image. Got the CanvasPanel. Not the Top “CustomUserWidget” as I expected. But this might be handy for you.

In case of the image not loaded properly:

UUserWidget* FindRootWidget(UUserWidget* CurrentWidget)
{
    if(!IsValid(CurrentWidget->GetParent())){
        return CurrentWidget;
    }
    return FindRootWidget(CurrentWidget->GetParent());
}

This walks up the chain to get the outer most widget (works for widgets inside of widgets).

UUserWidget* UFPMScreenWidgetBase::FindRootWidget()
{
	UObject* CurrentWidget = this;
	while (true)
	{
		UObject* CurrentWidgetTree = CurrentWidget->GetOuter();
		UObject* TreeOuter = CurrentWidgetTree ? CurrentWidgetTree->GetOuter() : nullptr;
		if (TreeOuter && TreeOuter->IsA<UUserWidget>())
		{
			CurrentWidget = TreeOuter;
		}
		else
		{
			// Reached top level widget.
			break;
		}
	}

	return Cast<UUserWidget>(CurrentWidget);
}