(this is my first post to the forum, please let me know if I put this in the wrong area, and I’ll move it)
I have a small project. The project has tiles, which are widget blueprint objects. The tile has an image I put a default texture on the image at startup time. I’m trying to replace the texture at runtime.
Here is the heirarchy from the designer. Both TileButton and tile_image are variables and visible.
What is the proper way to use this brush (texture) to update the image on the button?
I’ve tried a bunch of things so far by watching videos, but I haven’t been able to make any
of them work, and I think I have a fundamental misconception about what I should be doing.
Things I’ve tried:
Getting the image object setting the brush on it (nothing changes visually, though)
Getting the image object, setting the brush, and trying to save the tile_image (can’t, it is read only)
Using make slate brush from the 2d texture
SetTileBrush calls SetBrushFromTexture passing in the “brush” as a texture
Getting the button, setting the style, setting normal style to a call from set brush resource to texture with the passed in texture
Making a slate brush from the passed in texture, calling make button style, and setting the style
Videos I’ve tried using for reference:
Search terms I’ve tried:
“unreal engine how do i change a button’s image at runtime?”
“unreal engine set texture 2d on button”
“unreal engine cant draw texture2d onto widget”
It’s possible you have set the texture correctly but there is a size/scaling issue. If match size is true and the texture size is very small, it may be hard to see a change.
I recommend checking Tile_Image properties to see if there is something gone awry there, maybe image alpha is set to zero, texture size is zero, Draw As is set to None etc.
Worth double checking those kinds of values.
Another thing to try is to set up a test with the tile widget in isolation. If you can update a single tile widget’s image texture correctly, then there may be an issue with the container or how you are calling SetTileBrush.
When I try without MatchSize checked, the result is the same.
The tile already has an image on it which was set at tile creation time, I am trying to replace the image. When SetTile runs, the old image remains, and no sign of the new image.
However, these properties don’t mention alpha or size, so it could be that I’m looking in the wrong place for tile properties. (By the way, I renamed “Set Tile Brush” to “Set Tile Brush1” in these examples)
I tried calling the test widget in isolation - There is a layout class which is the parent of the tile grid (which is the parent of the array of tiles). I added a W_Tile instance to the layout class, and called the Set Tile Brush method there. It has the same problem.
B. Checking the order of events - maybe the function call to “Set Tile Brush” was happening after the create event. Turns out that the tiles are being created before the tile grid which calls “Set Tile Brush”. Since the tiles set the default image when they are created, if they were called too late, the default image would overwrite the one that “Set Tile Brush” is trying to set. I called “Set Tile Brush” on a mouse click event, but still the image is not getting updated.
One idea - one of the videos that I watched called a “set” method after calling Set Brush From Texture. Is there something I need to do after the call to “Set Brush From Texture” to make sure that the change sticks? I haven’t been able to call a set method on the image since tile_image is marked as read-only in the designer. I have made it a variable, but I still don’t seem to be able to set it.
Function we use to change a button image at run time. C++ but should (?) be straightforward to convert to BP. This function is in a base class that’s parent of all our HUD blueprints.
Struggled with this for a bit as well, but long story short: you have to set the image for each button style: Normal, Hovered, Disabled, and Pressed.
If there’s any other way I wouldn’t mind hearing about it.
// in .h file
void SetButtonImage(UButton* button, UTexture2D* image);
// in .cpp file
void UBaseHUDWidget::SetButtonImage(UButton* button, UTexture2D* image)
{
// validate button and default icon
if (button != nullptr && _defaultIcon != nullptr)
{
// if image is null use the default icon
if (image == nullptr)
{
image = _defaultIcon;
}
// if the images match then do not set the images again
// must set the image for each button style
FButtonStyle buttonStyle = button->GetStyle();
if (buttonStyle.Normal.GetResourceObject() != image)
{
buttonStyle.Normal.SetResourceObject(image);
buttonStyle.Hovered.SetResourceObject(image);
buttonStyle.Disabled.SetResourceObject(image);
buttonStyle.Pressed.SetResourceObject(image);
button->SetStyle(buttonStyle);
}
}
}
Using it would simply be like this, assuming you have a pointer to an image and button.