When Should You Call Resources.UnloadUnusedAssets in Unity Open-World Games?
To control memory growth, we execute Resources.UnloadUnusedAssets RUUA when opening full screen UI such as the inventory or map. However, calling it causes noticeable UI stuttering, while skipping it allows memory usage to keep increasing. Our project is an open world game with seamless maps, so there is no natural scene transition where cleanup can occur. It feels like we're stuck between two bad choices. When should Resources.UnloadUnusedAssets actually be called? How do open world projects solve this trade off between memory growth and frame stutters? https://uwa overseas public.oss us east 1.aliyuncs.com/uploads/markdown/ccb6811f 9c67 4061 b9be 9403fcd433e8.png
Many teams encountering this issue immediately try to adjust when is called. In most cases, however, the real question is not when it runs, but whether the call actually releases any assets . A good starting point is to open the GameOptim GOT Online analysis report and examine the Asset Count curve, paying particular attention to the changes before and after each RUUA call. Under normal circumstances, if RUUA successfully releases unused assets, the Asset Count should show a noticeable decrease. If the curve remains almost unchanged, the call most likely released nothing and effectively became an "empty run." https://uwa overseas public.oss us east 1.aliyuncs.com/uploads/markdown/1149f045 e042 48fe 9118 8f25a34fe02f.png In this situation, the problem is usually not that RUUA was skipped. Instead, the corresponding AssetBundle may never have been unloaded. As long as an AssetBundle remains loaded, the assets it contains generally cannot become eligible for release. Even if RUUA executes successfully, it may find nothing that can actually be reclaimed. As a result, Unity performs a full resource scan, introduces additional main thread stalls, and frees no memory at all. For this reason, it is generally better to reverse the troubleshooting order: First, verify whether RUUA actually released any assets. Then evaluate whether the timing is appropriate. If the Asset Count curve shows little or no change after the call, the AssetBundle unloading strategy should be investigated before continuing to adjust the execution timing. There is also another scenario that is intentional by design. To avoid repeated loading and the resulting frame spikes, many projects deliberately keep certain AssetBundles resident in memory. If those bundles are intended to stay loaded, RUUA naturally cannot reclaim the assets they contain. In this case, repeatedly calling RUUA is usually not the best solution. A more effective approach is to implement a tiered AssetBundle caching strategy , for example by managing bundle lifetime according to: Least Recently Used LRU Player location Distance from the player High priority resources remain resident, while lower priority AssetBundles can be unloaded together when memory pressure occurs for example, after is triggered , followed by resource reclamation. Regarding execution timing, two approaches are commonly used in production: Execute RUUA at fixed intervals, such as every 5–10 minutes. Trigger cleanup in response to when the operating system reports memory pressure. Executing RUUA while opening full screen UI such as an inventory or map is also a reasonable option because players generally tolerate a short wait during these interfaces. However, this only makes sense if the cleanup actually frees resources rather than performing another "empty run." Ultimately, instead of continuously changing when RUUA is called, it is usually more valuable to confirm that each execution genuinely reclaims memory before deciding on further optimization.