Introduction & Background Context
Ever since the debut of CanvasGroups back in 2022, I’ve been making extensive use of them in virtually any instance where smooth transitions were needed for a group of UI elements.
They function as expected if used sparingly, however - upon implementing more complex interfaces, especially the nesting of CanvasGroups - we begin to run out of texture memory very quickly. This becomes very prevalent on lower graphics settings, as the memory limit is much lower.
As there is no built-in method to clear inactive CanvasGroups from texture memory - they continue to consume memory, even when their Visible
property is set to disabled.
The automatic system that manages texture memory is unpredictable under the load of many canvases and frequently causes canvases that should be visible to fail to render entirely.
My Use-Case & Initial Impressions
In my experience, I’m making an avatar editor interface that utilizes CanvasGroups both for category pages and subcategory pages. As a result, I’m using a lot of canvases to transition between these different pages smoothly.
Pages are set to Visible = false
when they are inactive - yet they persist in texture memory until they are reallocated by other canvases. I’ve frequently noticed that, when clicking through these pages, despite being visible - they “sleep” until they are woken up by an update (i.e. hovering over them).
Consequently, this leads to many visible pages rendering as completely blank until the user interacts with them by tapping on or hovering over them - completely ruining the user experience.
Preliminary Testing & Observations
At first glance, I would have expected the Visible
property of the CanvasGroup to clear the contents of the canvas from texture memory when set to false
. This does not appear to affect memory usage, presumably for caching and efficiency purposes.
After performing some further testing, it appears the only way to clear CanvasGroups from texture memory is to simply destroy them and re-instantiate them later if they are needed again. This is not a scalable solution, especially for intricate interfaces involving many sub-elements.
Thus, unless you’re only using a few of them, the only solution to these canvas issues is to simply not use them. This severely limits the creative application of CanvasGroups, and is quite demoralizing, especially after creating an entire interface using them.
Proposed Solution & New Member APIs
Perhaps a couple of member functions could be added to the CanvasGroup class - something along the lines of :SleepCanvas()
, which would clear the canvas from texture memory prior to changing it’s visibility, and :WakeCanvas()
, to request its contents be redrawn, respectively.
Alternatively, clearing the canvas contents from memory when the CanvasGroup is not visible (Visible = false
) would be ideal and lightweight, however, I’m not sure if this approach would cause unintended texture flickering or negatively affect other experiences.
Note that these are simply my initial implementation ideas, and may not reflect the final changes engineers make with regards to this issue. Feel free to leave any suggestions below.
CanvasGroups are an incredibly powerful resource for creating stunning & detailed user interfaces. If this issue is addressed, developers could use as many of these canvases as they’d like, granted they take the proper memory usage precautions using whichever approach engineers decide on.