Image gets passed to Child Widget, but String does not

I have a main widget that runs a loop through a path of data assets and populates a child widget with information for each one. PDA_Things is a primary data asset with 2 data assets of that type in the selected path. The problem is only the images get loaded into the child widget but not the string/text values. Why is it only getting the images and not all the variables? I have the variables bound to the slots and editable and expose on spawn selected for all of them.

Here is the main widget and the relevant part of the loop:

Here is the child “Item Container Widget” Pre-Construct and showing the bindings.


When I put in break points in I can see the variables have the correct data as seen in the print string here:

4 Likes

i’d suggest try using onInitialize as pre/construct execute in times that you are not intuitive. sometimes not when you want.

1 Like

Like this? No such luck, still the same result. Unless I did something wrong?

Expose on spawn for widget properties has been bugged for ages. At some stage the properties are (somehow) not loaded in yet.

*Edit linking my reports:

CreateWidget Bug - exposed property pins NULL on OnInitialized, useless.

Instead of running it on PreConstruct, can you try running the same code on Construct or OnInitialized? If that fixes it, I recommend not using the expose on spawn technique, but writing an initializing method for the widget to call right after the “create widget” node.

Also useful to know, PreConstruct runs in both editor and runtime. PreConstruct and Construct can run multiple times (any time the widget moves in the hierarchy for example). OnInitialized runs once at runtime.

yes that is correct. if that does not work then maybe the string variables are not serializing properly.
make sure they’re not transient.
also Roy’s suggestion for a setup method seems better.
i don’t recommend Construct (or pre construct) for these things. as Roy said, they can be called in other times too, and not always when it’s spawned.

Interesting so I initialized the widget as you suggested, but now nothing including the images get loaded when I try to add them after the fact. I even tried to initialize with the proper variables instead of just hard-coded placeholders (as seen here) and no dice. Here is the full code maybe I did something wrong?

I removed Expose on Spawn and am using OnInitialized. I also am not sure how to check if the variables are serialized properly, best I could do was check the “Save Game” option on them in the Item Container widget but that did nothing so I unchecked them again.

Also sorry for the rats nest of code, I swear it was more organized before I started debugging this haha

2 Likes

On that code you’re showing, the print string nodes print incorrect? the image pointer is invalid there? or are they fine at that point?

*Edit added image example of how you can progress in next post. You can see there that there is no direct need to store the data in properties as well, since you can directly set up the widgets. I am assuming that your properties (if you are still going to use them) are not overridden / cleared / in a binding elsewhere.

“CreateWidget” node Owning Player is nullptr. I’d swear that causes another bug I reported time ago but I can’t remember it. Best set it aswell.

Edit* This was a case with Slate widget construction, irrelevant for your situation but that explains why I thought of it:

[Bug Report] Adding UWidget causes widget tree corruption

Blueprint Assist plugin fixes the horror of blueprint reorganizing as it automates.

2 Likes

1 Like

The Print strings were working at the start of this, but they aren’t now.

Should that Initialize Function be in the Item Container Widget or the one I’m calling it from?

I will look into that plugin thanks!

2 Likes

What I did for the example was open the level blueprint (quick and dirty), then call CreateWidget + InitializeWidget there just to show how I initialize my widgets. I didn’t make it more complex than the base example needed to be (like adding it to viewport etc.), It’s easiest to debug from a simple situation.

That InitializeWidget function is part of the UserWidget which contains its (Slate) textblock. In my example the text is set directly on the widget and not stored in another property on that UserWidget, because there is no need to store it twice.

If you recreate the same basic setup, it should work fine. If it works fine, start adding complexity in steps (like try reading that asset registry data), before adding everything at once.

1 Like

Ok I finally got it working. I think Initializing definitely helped and I also had incorrect wrong logic as well. Not setting the variables BEFORE I added the Child seems to be my biggest mistake, (seems obvious in hindsight). Thank you guys so much for the help! For anyone that needs it here is the resulting code. It’s not pretty right now but I still have some more work to do.

Main Widget

Item Container Event Graph

Item Container Function

Cheers!

1 Like

don’t forget to link that texture pin :wink:

1 Like

That’s just a placeholder for initializatiion, the images are stored in the data assets. In the case there is no image avaialble it will show our company logo which is what is in there. Thanks though good eye!

Oh alright :slight_smile: . Probably you only need to set the text and image properties of the widget just once. The InitWidget method is just a setter method which you can fill with the data from the data assets directly.

Currently it fills with the placeholders first, and is potentially called multiple times with the same data (because it’s in the Pre/Construct method.).

Good you got this working, improvements and optimization can be done later.

Exactly, trying to roll this out for a conference in a few weeks and it just needs to be MVP level for now!

Hey while I have you, don’t suppose you know an easy way to pass an object reference for each data asset to each created button do you? Idea being whatever button a user clicks will call a spawner blueprint and load whatever static mesh is in the data asset into the blueprint construction script. Already have the spawner made just need a way to send the data asset over when I call spawn.

I know it’s a different question so no worries if not. Thanks again either way!

First off, make sure that the BindEventToOnClicked node is within the widget’s OnInitialized method. Because it should only bind once! :slight_smile:

Sure, if you set up those buttons as well with a similar “initialize properties” function, and pass in an object pointer, you can process that object pointer per button. It’s the same as how you were storing those texts and image pointer on the other widget. Either you store the class pointer on a button or on the menu containing the buttons. In detail:

There’s two ways to setting up those buttons.

  1. The widget containing all buttons listens to which button is clicked, then decides what to spawn.
  2. button widgets are turned into UserWidget, storing a property of type class pointer (what to spawn) and handle spawning logic on their own when pressed.

Usually it’s most common to just use generic buttons (they can be pressed, nothing more) and have the menu deal with what happens if they are clicked. (option 1 I gave). That avoids having to create tons of button variations.

The property type you want to use for storing “what to spawn” is a class pointer. This is the purple pin / node in blueprints. If you need to be memory efficient (mobile devices, potato PC etc.) you also want to work with soft pointers, unless you want to load everything in memory at once.

You can directly select the class you want there. for spawning actors, you could select Actor instead of Object. You can also select something more specific or cast to that later.

After you spawn the actor, you probably also want to store what’s spawned in an object instance pointer (the blue pin variant of what you did earlier). Then you can delete it in the future before spawning something else.

That’s a different topic. What you want is to spawn something at runtime when clicking on the UI. Blueprint construction script (as the literal name) is something else.

Oh right, missed that. I assumed you’d just spawn from within the widget directly. Barely makes a difference. You can have a “central manager” actor for spawning (if the widget isn’t one already), but then you’d create that just once right? you wouldn’t create multiple spawners because 1 is enough to act as a factory for further spawns.

What your image is showing currently is that for every click you create a new spawner (intended for spawning things). And that doesn’t yet spawn something on the screenshot.

1 Like

Yes I already have the “factory” made I just need to pass it the dta asset.

Once I get that working I planned on adding a method to handle the rmeoval of whatever was last spawned to clear the way for the next object.

I’m having a little trouble figuring out how to get the soft object reference thought (yes this is for mobile)). I have the variable in the child widget, initialized it and all that. I just am not sure what to choose once I pull off the data asset package from the for loop. Assuming that’s where I’m supposed to be picking it up from that is.

Nevermind I figured it out class ref duh. Sorry it’s late here my mind is spent. I’ll report backl tomorrorw if I get it working. Thanks!

1 Like

Since it’s for mobile and you should use soft pointers, here’s some documentation

All about Soft and Weak pointers | Tutorial

Soft pointers can be loaded in sync or async. Basically you want as much as possible, especially class and asset (texture etc) pointers to be soft pointers. once you have a “hard pointer” (blue object instance pin, purple class pin) just anywhere then it’s already loaded in memory. In mobile apps that blows up memory.

That asset thing pin where you put the question mark on your screenshot doesn’t seem to return soft pointer? I don’t work with that asset registry system myself. Try to use soft pointer where possible, else ignore it for now. If there are memory problems you’ll measure them in testing post development.

Might not be here for some time, skipped the night and have to do some things before I get some sleep.

Well I really appreciate all your help, you have massively helped me move the ball forward. Get some rest, I’ll follow up and you respond if/whenever you feel like it. Thanks again!

1 Like