Add/remove Image at runtime for UMG?

I’m building a procedural ammo display system that will automatically increase/decrease the number of displayed bullet images depending on the defined max ammo for the weapon at the present time (i.e. the weapon might have a max of 30 rounds, 45, or any other arbitrary integer) and I’ve built a material that will automatically resize the bullet icon based on the current max ammo value.

What I need to do is create an arbitrary number of Images in UMG which can then be added to an array, and process each one individually (so that its color can be changed depending on whether or not that round has been fired, as well as any alternate attributes about that round such as bonus damage dealt by it, etc.) using a loop.

The problem is, there doesn’t SEEM to be a way to create a reference to an Image asset at runtime. You can generate a Slate Brush and ASSIGN it to an image, but without creating a unique image widget in the Viewport editor UMG doesn’t seem to recognize it. I tried creating an array of Image-type object references, resizing it, and then setting the corresponding values for each of its members and assigning them to render as a part of the master ammo readout widget using Add Child to Canvas (under the assumption that UE4 would simply create arbitrary image object references to fill the array) but it doesn’t work.

It seems like there ought to be a way of doing this WITHOUT just creating like, 99 identical Image widgets, hiding them, and then assigning attributes to and unhiding the appropriate number as-needed, but I can’t actually figure it out.

How does one create Widgets (not user-defined widget blueprints, but CORE widgets like Images, Borders, Buttons, etc) at runtime?

Hi there, I think I have a solution to your problem, do you still need help with this?

I don’t, actually, as I’ve since given up on it and implemented an alternative that uses polar coordinate UV mapping in the ammo counter material to transform a tiling grid into the necessary circular ammo display of arbitrary division.

But if you’re feeling kind, I’d ask that you post your solution ANYWAY so that I or anyone else who runs into this problem in the future (when dealing with a more general case than mine) has access to a solution

I have this problem too, so please post your solution!

I’d also like to know if there is a way to create base widgets and add them dynamically.

Currently I still wrap them into widget blueprints, so that way they can be added/removed from boxes such as horizontal or vertical box, at runtime, depending on how many you need. This works great if a widget needs to be complex (eg inventory item, with its own tooltip, text boxes, click behavors, etc), but its an overkill if I just need to add a simple TextBlock at runtime (eg for chat)

I used same technique messages, just made little bit advanced, so each message use few premade text boxes if it doesn’t fit, pretty stupid technique.

Alright so in terms of dynamically adding an image, a hack around I found to be useful is making a new widget and removing its canvas, adding an image and setting its screen size to ‘desired’ so no matter how big or small the image is, the view is not restricted. Go to the graph part of the widget and create a slate brush variable with any default texture. Go back to the designer, click on the image and navigate to Appearance -> Brush part of the image properties and bind the brush to your slate brush variable. This way, you can set the image to change dynamically when later created.

When you want to create this said image, just use the ‘create new widget’ node, add it to viewport or as a child of another container and add it to an array for reference or add a tag variable to it to find it later using ‘Get all actors of class’ node, you can drag off the widget reference from the create widget node and set the slate brush variable to change the image texture dynamically. In your example of the bullet, you’d create a userwidget of an overlay container, with the bullet’s image inside it then you’d create the image widgets as children for the overlay container with the right Z depth to overlay your bullet with the effects you want. You can create any combination of widget components without use of canvas in a widget blueprint with the screen size being ‘desired’ and dynamically create it without much hassle. Shame there isn’t an easier way to create an image, but this way is robust and tested and I haven’t had a problem with it. Hopefully that helps. Any questions, I am happy to answer or clarify.

2 Likes

Please make a video example as visual example?

1 Like

I am using function construct object where class is Image. After object is created you can add it to panel by function add child. But it is just for example

1 Like

Appreciate that this is an older post but as it still tops some google listings I have a solution that i will post here.

this answer assumes that you already have your weapon firing and that you have a function or event that updates the number of rounds left in the players magazine.

first up you need to create a widget that will display the ammo, in our case this widget also included a number for the amount of magazines remaining as well as an icon for the weapon the player was carrying. So in our case we created the widget like so:

  • First up we used a scale box - this is mainly so that we can add the widget to another parent (HUD) widget and change its scale.
  • Inside the scale box is a size box.
  • inside the size box we use a canvas panel - the canvas allows for multiple image children and makes it easier to manage.
  • No inside this canvas we have an icon for our weapon, a text box to display the number of magazine and then another canvas panel.
  • the second canvas panel is where the magic happens, containing 40 bullet icons in 4 rows of ten - you should still place and anchor these manually.

once you have set up the widget you need to create an event or function within and bind this function/event to an event dispatcher that broadcasts when the number of rounds changes.

The function/event can then run something similar to he following.

THIS IS THE ANSWER RIGHT HERE! THANK YOU!!!

PLEEEEASE MARK HIS MESSAGE AS THE SOLUTION FOR OTHERS!!!