Widgets Construct order, and passing variables.

I tried about everything, and i cannot make clean code that passes actor references properly.

Setup:

  • bunch of actors (planets) spawned at runtime, so i cannot set their widgets in editor.
  • each planet have informational widget, and i cannot set that widget reference/pointer during map creation. Again those are assigned in runtime.

Getting all actors of class, then passing that information to master widget is trivial, but after that it is mess.

Master widget spawns one info widget (custom user widget) per planet in level. And passing reference to planet works.

Then that planet widget should pas that reference to its children widgets. And here problems start.

This is printed by all widgets in chain of passing planet reference:
LogBlueprintUserMessages: [_UMG_PlaceFleets] ==== None
LogBlueprintUserMessages: [_UMG_BoidsBar_C_0] >> None >> CPP_Faction_0
LogBlueprintUserMessages: [_UMG_BoidsBar_C_1] >> None >> CPP_Faction_1
LogBlueprintUserMessages: [_UMG_BoidsBar_C_2] >> None >> CPP_Faction_2
LogBlueprintUserMessages: [_UMG_Side_PlanetInfo_C_0] Side: >> BP_Planet_Geoid_C_7
LogBlueprintUserMessages: [_UMG_Side_PlanetInfo_C_0] Side: >>>> BP_Planet_Geoid_C_7

All print it on event initialized. (I also tried construct and pre construct). All those widgets are created by blueprints and have planet reference passed on spawn.

_UMG_Side_PlanetInfo is created directly by master widget.
then rest of spawning is like this:
_UMG_Side_PlanetInfo >> _UMG_PlaceFleets >> _UMG_BoidsBar

Yet all is printed in different order, so they are initialized out of order. Similar thing happens for event Construct.

I cannot pull information from parents, due to same problem, child is not always initialized or constructed after its parent.

Is there any way around all that besides infamous Delay 0.2 sec?

I solved this (but imo it is dirty solution) by creating dispatcher that fires 0.2 sec after game begin, and triggers passing correct planet reference to each widget.

And extra bonus:
There is “Named Slot” which is great for making modular user widgets, however same problems apply, and on top of it i cannot reference “future” widget inside named slot, because it is not there during coding/editor time. Any tricks for passing variables to such widgets inside named slot from parent?

You could access the parent widget to get the actor variable instead of storing it in each child widget.

Implementation:

Simple: get the outer widget and get the desired variable.
image

However, this method is not flexible. It would be better to implement this via an interface:

  1. Let’s create the top Level_0 widget and two successively nested Level_1 and Level_2 widgets. I added Level_2 two times to work out two use cases.

Level_0:

Level_1:
image

Level_2:
image

  1. Then Create a Blueprint interface with the following function:

Add the interface to widgets:
image

and override GetActorVar in every widget:

Level_0:


Level_0 contains the variable, so we just return it.

Level_1:

Level2:

  1. Usage:

Level_1:

Level_2:

Result:
GetVar

You can also get the content of NamedSlot using this function:

image

I hope it’ll be helpful to you.

My Products

1 Like

Huge thanks! I will try this in my prototype gui project.