How can I "freeze" a Slate Widget so that it doesn't update every tick?

I have a rather complex script called from the “OnPaint” event in one of my widget blueprints that procedurally generates a minimap based on the game state.

]

However, OnPaint calls every tick and when the script iterates through thousands of indices multiple times, every frame, it amounts to some crazy and unnecessary fps drops. This only needs to be called whenever the relevant gamestate updates, usually once or twice every second max. I tried only running the script on update frames, but it appears as though it completely resets and skipping the script results in nothing being rendered on every other frame.

I feel as though there might be someway to cache the fully painted widget and display that on subsequent frames, and then just update it as necessary, but I have no idea I might go about doing it. I’m not afraid of getting my hands dirty in C++ either, I’ve just been trying to build out the UI solely in blueprints but this is too big of a performance hit to ignore.

1 Like

Slate caches widgets of the box and paint only if widget when they are invalidated with Invalidate function:

Widget also raports if it volatile, which means it changes on every frame and need paint on every frame, you inform Slate about this via overriding ComputeVolatility, if widget is volatile return true.

You can also invalidate widget (but only geometry layout) on UMG side

So I looked into Volatility but I’m pretty sure the Widget is never volatile, and unfortunately the cached geometry of the call is the issue. Here’s a sample image being generated:

256999-capture2.png

And here’s the CPU Profile breakdown:

To my understanding, it’s all the DrawBoxes geometry, cached or not, in “onPaint” that’s causing the issue. I think I need to actually “snapshot” the frame itself and update an overlay with it until I need to update it.

So for anyone that runs across this, there is a custom widget element called an “Invalidation Box” specifically created to cache/freeze parts of your display. Documentation here:

1 Like