Dynamically create slate brush image in a widget blueprint

Hi,

I wounder if it’s possible to create a variable no of slate brush images in a widget blueprint, depending on i.e. string array representing no of levels. Maybe through the construction script panel? My goal is to basically have a variable no. of slate brush images representing the length of a string array with names of levels. If the string array changes in editor mode it should update in i.e. construction script connected to a widget blueprint.

Thank you!

Not sure if I follow.

Yes, you can dynamically create Slate Brushes.
Yes, you can set an Image for every brush.
Yes, you can create as many as you need in a loop, based on a length of another array.
Yes, you can do it in the construction script.

Or are you asking whether it’s possible to dynamically and procedurally create Images - because that’s what I’m getting. You can but it’s not exposed to blueprints, afaik.
You can use materials as SlateBrush Images, if that helps. Dynamic material instances, too, I think.

Widgets exist only as a part of the viewport (apart from residing in memory) which does not exist until you PIE. So you can’t really preview them in editor mode. Perhaps you could attach it to a widget component and drag it into the level. That could work.

Somehow I think I completely misunderstood the question. Perhaps you could tell us what you’re trying to achieve. Is this supposed to be a map selection menu but you do not know the number of levels upfront?

Hello!
Thanks for quick response. Sorry, I know I might expressed my aim for this purpose a bit unclear, as I am not from a programmer background but yes, the aim is like you explained in the last sentence “…to be a map selection menu but you do not know the number of levels upfront”. At the moment I have a combo box as map selection but I like to visualize it with images in slate brushes. Please see attached sketch image.

The pic is pretty helpful and the layout and functionality straightforward to achieve. A couple of observations:

  1. Why use a combo box - in most cases it’s a user unfriendly element that works well when there’s limited screen space. My assumption here is that this will be a main level list and the menu on the right is a list of sublevels. There might be a plethora of reasons why you’d want one, though, so your call.

  2. Using slate brushes like you intend is going to be cumbersome. May I suggest you actually use full fat widgets for the horizontal sliding selector. Design one with a border, image, text and any bells and whistles you desire, and then populate a scrollbox with those custom widgets. This will be much more flexible than fiddling with slate brushes.

Which part of the setup are you finding problematic at the moment? The whole shebang?

Thanks for your input, really appreciate it!
I am a bit new to effective way of setup functionality so bare with me please,

  1. Just used the combo box for a quick start but not for any vital purpose. Exactly… basically I just need one widget displaying scrollable image, derived with the no of images from length of a string variable representing level maps.

  2. When you say full fat widget, do you actually mean set up a widget as a child with just the border, image and text with e.i. 200x120p? Then setup a parent widget with a scrollbox and by “user created” insert the child widget? I wounder if the function of distributing the child widget dynamically, in correspond to the string array length should be in the parent widget? Or should it be created in an actor placed in the main level? Am asking as far as I know the actor has the construction script available right?

My theory is like: in the construction script; check the string array var length and do a ForLoop to create child widget (border image and text) - which updates the parent widget with the scroll box and horizontal distribution.

In the whole context I am just a bit confused of how to tie the whole shebang. If you’re able to just sketch a quick setup of the different parts I appreciate it.

Thank you!

Hey, sorry about the wait. Not going to reinvent the wheel here but if you want to construct something like you envisioned, here’s one way to do it and link it all together:

Parent widget [LevelPickerParent] houses 2 custom widgets - [LevelPicker] and [SubLevelPicker] which both have a Parent variable of type [LevelPickerParent]. When the [LevelPickerParent] is constructed, it sets *Self *references in the children so they communicate back (bottom left). The [LevelPickerParent] also has two Events - one for *AddingLevels *and one for EmptyingScrollbox.

The [Level] widget shows the info about the level and has a couple of exposed variables (Image + Text) that are set by its own constructor as they are being added to the *Scrollbox *of [SublevelPicker]. The code is in the bottom right; and this is where you choose *SublvelName *and the Image.

I tested this *very *briefly and it seemed to do what you wanted. Apologies for the chaotic nature of the image below and arrows pointing in all directions. Let me know if something does not add up.

If you wanted to reduce complexity here, you could skip the 2 custom widgets and manually put [LevelPicker] & [SubLevelPicker] elements into the same widget.

Hey Everynone, no worries about the wait, I appreciate your time! I think this is a great setup and thanks for the explaination! I’ll go ahead and check how it works and I’ll get back. Thanks again!

Hi again, I think the workflow is really good to start/ build on. I haven’t fully completed the test on my setup but tried focus on one step.

Anyways, I tried solution to skip the combo box and and derive from the string array var directly.
Then in your LevelPickerParent widget, I tried your tip to reduce and do the FoorLoop and what follows in “Event Construct” instead of “On Selection Changed” as my goal is for the child widgets to appear on BeginPlay, corresponding to the string array info that the user puts in editor mode if that make sence.
It works fine, altough I seem not to be able to expose the variables of LevelName and Image? They should appear on CreateWidget node within the FoorLoop right? Double checked that they are public. Please see attached image.

Did you say you put the scroll box in the LevelPickerParent? That’s what I tried in my parent widget.
Could I ask, do you think I am in a need of the “Set self references” in the event construct of LevelPickParent?

My next step is top work on the horizontal alignment of the child widgets.

Thank you!

In the details panel, where you made them Editable, there is *ExposeOnSpawn *tickbox. That should do the trick.

I followed your guidelines (see the artsy sketch :smiley: ) and created two separate widgets. And a 3rd one to tie them together and make the communication between them easier. This is where setting references comes in. The Parent knows about both of them and serves as an information hub. Have a look at the hierarchy shown in the pic I posted, the upper left corner. But that also means that those 2 widgets need to know who the parent is. So in the [LevelPickerParent] Constructor, I access those 2 custom widgets’ *Parent *variable and set them accordingly.

Nope, it sits in the [SubLevelPicker]. Have a look at the hierarchy. You’re dealing with 4 widgets in total here.

What you can do, is to create only one big widget that has it all, and not worry about communication at all; depends on how complex this thing is going to be. From my own experience it helps keeping things small and modular.

Thanks, the “ExposeOnSpawn” did the trick!
True, you did follow the artsy sketch and you did a great job :smiley: I do see the benifits of the communication and modular setup for what you’re talking about.

Excuse me for being a bit lost, just trying to look at the SubLevelPicker hierarcy and where the scroll box is located? I do see you get it in the “Add Level” event. Is there an advantage to have it placed in the child widget rather than in parent widget? Also how do you set the self ref in LevelPickerParent? Did you create object ref or “create widget and promote to variable” for level and sublevel picker?

Talking about complexity, my end goal is to have the scrollbox to choose which map should be loaded depending on which Level name and index is some how in focus. Basically a typical game menu with sliding levels.
Just thinking freely: So let say you want to choose child widget 1 of Level by sliding. It will maybe overlap something and get in focus to trigger event of getting Level name and index.
Had an idéa of a button to hover over to slide the scroll bar with a certain amount of transfomation to left or right. Any comments on this?

@**SBK3d: **sent you a PM with the widget files, feel free to take them apart. Worth more than a thousand words. You should be able to drop all 4 into Content folder in your project and create just LevelPickerParent. It should all be self-contained.

What you are referring to is often referred to as carousel menu, I think. It’s doable, a tad fiddly, though. Have a look here:
https://forums.unrealengine.com/development-discussion/blueprint-visual-scripting/107870-umg-media-gallery

Maybe it helps a little. The animations showing it in action did not survive unfortunately.

Thanks alot for the widget files and the link! I’ll have a look through.

Hi, I got the “carousel meny” to work with the scroll offset + image width. With the link to forum you provided, I wanted to check if you had an idéa with the script “Buttons add offset (width of the image)”.
Know after each click, it scrolls and centers each child widget in my parent widget. I also made an array of each child widget which is created on the FoorLoop. The idéa I had was to somehow get the current index and string when a child widget is centered (in focus). Basically telling which map should be loaded when a child widget is centered. Could it be done with some kind of “isOverlapping” element?

Thanks

There is a better way than fiddling with offsets, you can scroll directly to a widget:

I’m not sure how you choose the levels at the moment as you must have gone through some redesign steps. Do you still use a comobox or?

Ok thanks for the tip!
At the moment am using OpenLevel node where am getting the string from the array and at what index the current string is at. I still have the combo box with the event on selection changed that get the array.

My idea is to use the same principle but With a custom event when the current child widget is in focus (centered).

Good day! Just wanted to share with you, I worked out a way to choose level by scrolling the widgets. It’s maybe not the most convinient way but it seems to work and I deleted the Combo box.

What I did at BeginPlay was to:

  1. Initialize a start level by int and do the scroll offset times image width, which sets the level widget in focus.

  2. At the same time am also setting a current level scroll int variable.

3 From that current level scroll am getting the matching string from LevelOption array and set it to name var that will load the map, when play btn is pressed.

Then am just adding or subtracting 1 and set it to “current level scroll” when setting the scroll offset.

Another topic I wounder if you can help with is basically about radial progress bar and trigger an event after time progression.
I have done a radial progress bar which starts on button hovered. Time duration for the progress can be adjusted but for now it’s set to 2s and after that the event is triggered.
If button is unhovered the time progress is aborted and so is the event to be triggered.

The problem am having is that if button is unhovered and hovered on again a couple of times before 2s has passed, the event will be triggered even though 2s duration hasn’t passed?
Basically I guess I need to know if the time which has passed (is that delta time?) from when I unhovered the button til I hovered over it again has passed the 2s. If not it should not trigger the event.

Am using a simple boolean to determine if progression bar is true or not depending on hovered button or unhovered.
So when on button unhovered, var “isAbortProgressionBar” is set to true which doesn’t trigger the event.
On button hovered var “” is set to false which trigger the event.

…I think I was looking for the “Retriggerable Delay” node.

Hello again Everynone,
I wounder a bit over the “Level” Widget you setup with “LevelName” and “LevelImage” variables. When you feed the LevelName you do it with a ForLoop. I did it with a ForEachLoop, taking the string array. Then I have a 2D texture array with images that I want to feed in to the “LevelImage” var. The thing is I don’t know how to feed both of these arrays into the Level Widget at the same time? When I try to do two ForEachLoop one of them will get overriden. It feels like I have the wrong approach here.

I did a test of making a custom ForEachLoop, built on the standard macro.
Added another array input and element output. Then added another array length for the branch check condition.
The custom ForEachLoop seem not to be able to handle wildcards so I set the input arrays to the types I needed as well as the output element.
It seems to work!