[UMG] Change text color on button child on mouseover

I’m trying to get text that’s within a button to change color on mouseover. Basically I’m making ‘invisible’ buttons where the state is indicated by the text within the button.

I’m not seeing anything like a “mouseover” event to grab, so I’m not sure how to do this.

Any advice is appreciated.

I spent a while looking for this kind of set up when I first started playing with UMG.

Here’s a quick dirty set up that works well. It’s late so that’s all I have the energy to make.

You have to set the Text to Is Variable.

Make sure to toggle between context sensitive if you can’t find the widget you’re after!

EDIT: I should really say what that does - Every tick it checks if the button is hovered, if it is, it makes the text black else it is white.

Create a button yourself with an image and stuff… A Border element for example has MouseUp,Down and Move events wich you can bind set the image and text visibility to hit test invisible when you do so

Edit: If you nest a border in a border element and set a padding of 5 to the first + an invisible color, you can bind a mouse move on that first border wich sets the “OnLeave” color. After that bind a mouse move to the inner border element and put your onhover stuff inside. this should also work without a nasty tick event consuming resources

I did the ‘tick’ solution, which works acceptably. Hopefully this is improved upon down the line, as both these are really ugly solutions for pretty basic functionality.

after 4.12 was released I’m getting strange errors where widgets seem to cache hovered state and are activated even when they are not hovered. Is anyone els experiencing this issue?

Just in case anybody else is led here by google, this is how to do the above without having to create an event tick

1 Like

Thank you Dale122!

Late of course. But suddenly someone will come in handy.
Do not forget to make the text visible in the blueprints in the widget window.

Sorry my bad english

Best regards,
Antary \o

There were inaccuracies. After pressing the button, the text was displayed in normal mode, instead of “OnHovered”. Fixed.

Sorry to hijack and necro the thread, but I haven’t seen a solution anywhere else that doesn’t require set up for every button. This solution only needs a reference to a container with the buttons within it (e.g. a vertical box), making it a lot easier if you have large (or multiple) lists.

Note: The decrements behave oddly with child variables, and there’s no need to create a variable of the child count (when I took the screenshots I even forgot to plug them in!) so instead replace them with a simple subtract math function.

Initialise:


At Event Construct the widget blueprint loops through all the children (in this case, buttons) in the vertical box. Each button is bound such that it when hovered over (OnHovered) it ‘shouts’ out to a custom function (OnHovered_Cust), and when unhovered over (UnHovered) it ‘shouts’ out to another custom function (OnUnHovered_Cust).

OnHovered_Cust:

When OnHovered_Cust is called it loops through each of the children (buttons) of the vertical box, stopping when one of the buttons is found to be hovered over (IsHovered = true). The child (this time, the text) of that child button is then found, and the desired colour change is applied.​​​ If this sounds confusing, what we’re doing is taking the vertical box, finding it’s children (buttons), and then finding the children of those children (the text in the buttons). The text box is assumed to be the button’s first child, so the Index in GetChildAt is set to 0.

OnUnHovered_Cust:


When OnUnHovered_Cust is called it loops through each of the children (buttons). For every button not being hovered over (IsHovered = false) it resets the text colour.

Overall Layout:

Implications:
At Event Construct each button is looped through and bound to an Event Dispatcher, meaning if this method is used for a large number of buttons there may be a brief performance impact whenever it initialises.

Because Event Dispatchers cannot carry information, each time the custom event is called it must loop through the children (buttons) to find which one is being hovered over. This means that for very large lists of buttons there may be a slight delay. This could be improved by splitting large containers into smaller sub containers (e.g. one very large box -> three boxes), so that there are fewer items to search.

Each box would require its own custom hover and unhover events, but this as simple as only the reference to the box (e.g. ‘Vertical Box 140’) would need to be changed. Alternatively, in C++ it might be possible to create a custom bind event with a ‘target’ output, meaning the custom function would be able to target the instigator button directly (avoiding any looping).

For anyone else dealing with this issue there is another trick you could use to avoid using Event Tick. If you do button > border > text. you could use the border to change the content color using event construct instead.