Recently I’ve been working a lot with HUD’s and UMG, and would like to know what the general consensus is from both Epic and the community as to how updating the information displayed on a HUD should be handled?
After looking at ShooterGame and various other example content, the general consensus from Epic seems to be that updating HUD’s on tick isn’t a problem, even relatively complex ones. ShooterGame has such a HUD, but everything is updated on tick, and it has little if any performance impact even though the HUD is blasting through a couple of thousand lines of code per frame, with casts and getters all over the place too. I imagine this is okay, because it’s handled locally only, and clients and servers know absolutely nothing of each others’ HUD’s.
In another project, the team I’m working with has taken every step to avoid doing anything on Tick in the HUD whatsoever, but this has resulted in a huge bunch of workarounds and reliable NetMulticasts and RPC’s that are required to update HUD information ONLY when the variable changes. Their argument is that updating on tick is generally supposed to be avoided. (I can understand that for gameplay events, but does it really matter for a HUD?)
So the question is, which is likely more expensive? The RPC / Multicast method (with 34 clients at all times) or updating on Tick? I’m siding with Tick being the best option right now, since it’s local and won’t hog bandwidth. I’m keen to hear others’ opinions on the matter though.
For those interested, we settled on the HUD and UMG updating itself on tick, the idea is we want to save as many calls as possible, as they’re more expensive, especially when the variables are already available.
I agree with you for using onTick on a local calls (i.e. HUD). I would avoid it for network calls as you have mentioned.
Glad you guys got it sorted. I guess if onTick for the HUD does become a problem you could then change this on your optimise pass of the code. Good luck with your project. 8-}
If you have to do a lot of computation, do it based on an event, cache the result and invalidate it later based on some other event. You can either make the result bindable, or set it directly on the widget to reduce delegate eval overhead.
If it’s directly bindable to a UMG widget’s property, use the property binding system in 4.7. It has been optimized to not use any VM code to evaluate the data. For a large complicated UI property binding can be valuable because it only means you’re evaluating visible items. If the widget isn’t visible it wont be evaluated. Depending on what widget’s tick you compute data in, it would be true for it as well, as ticks are not run on invisible widgets in 4.7.
In 4.7, the binding system also allows you to bind to native functions so you can do expensive stuff in native code faster than in blueprints.
If you’re just updating a players health, and some ammo for a few guns, you can do that in tick no problem. You really need to only worry about doing things in Tick if you’re dealing with a large RPG UI with lots of complicated items, and an inventory, and a spell bar and…etc.