Binding C++ variable to UMG widget without updating every tick

So all of my player data is in a C++ class that I exposed to blueprint. I used get nodes to grab the value of the stats my UI displays, set nodes to assign those values to a variable in blueprint, then used a binding to ensure that whenever that variable changes, the UI updates in turn:

Values set in main HUD blueprint:

Function run by the property binding hooking the value to the health bar slider’s fill percent:

The problem with this setup is that as the player’s data changes in the C++ class, the binding fails to update its value on the HUD, as that binding is pointed at a blueprint variable. I don’t want to constantly re-acquire that value in the blueprint’s event tick, as that would be ludicrously inefficient, is there any way I can give blueprint a pointer to the data, and trust UMG to update itself when the value in that address changes?


so these Variables are located in your PlayerCharacterClass, right?

Why don’t you just get the PlayerCharacter directly INSIDE of the binding and instead of setting the HealthValue variable, you dismiss this one and directly
plug in the result of the division into the ReturnValue.

You just need to make sure, that the “ReturnNode” is reached in all states. Means: If you cast the PlayerCharacter Return, the “Cast Failed” exec must
reach the ReturnNode. I normally use a Local Variable for the Return and for all fails (cast, not valid etc) i just fill the variable with a standard value.

Oh hey, that’s an excellent idea; the casting is still a bit expensive, but it’s massively cheaper than running event tick. For the local variable handling returns, am I correct that I don’t even have to Set it to anything, so long as that class’s constructor will initialize any needed variables by default?

If it is a variable that is set to something you want to work with, then yes. If you for example have an FString for this Local Return in the binding Function, then you might want to fill it with “Not available” or something
like that instead of an empty text. But here it is a float, so you could just not fill it and it will return 0. Or am i misunderstanding something here?

I just finished rewiring everything and this works perfectly- thank you very much for the suggestion :slight_smile:

You’re welcome (:

What I do is to instead of calculating the value inside of the binded function, I just bind a variable, and then in a seperate function I calculate the variable, then I call this function whenever I need to update it.