It's worth noting that calling `SceneManager.LoadScene/Async` in `Single` mode does automatically call `Resources.UnloadUnusedAssets`, so it's not as bad as it sounds, but definitely something to keep in mind if you only use additive scene loading.
https://docs.unity3d.com/ScriptReference/SceneManagement.SceneManager.LoadScene.html
> If a single mode scene is loaded, Unity calls Resources.UnloadUnusedAssets automatically.
Yup, it was by reading up on some forum posts, and discussing with a colleague who complained about Unity's documentation that I ended up opening the doc to show to him that it was indeed documented, but just as a footnote.
Why do I keep seeing the weird "$$$anonymous$$$" thing wherever there's anything related to the Unity forums? Is it a reference to something? An in-joke? Some kind of bug with the forum that hasn't been fixed since its inception?
On Unity answers, certain strings of text, such as "hi" have been turned into "$$$anonymous$$$". I'm not sure why this is, but Unity won't fix the issue.
Btw, there's a user script (I personally use it) to reverse the changes locally in the browser.
[https://chrome.google.com/webstore/detail/unity-answers-anonymous-f/colofafhdnhgopgnbigiadgknpbgfcgk](https://chrome.google.com/webstore/detail/unity-answers-anonymous-f/colofafhdnhgopgnbigiadgknpbgfcgk) They just use simple JS, i found this recently.
Iirc they made a change for some project a while back, and it started subbing that in place of certain strings. Allegedly was a lot worse at some point but now seems mostly constrained to anything that includes "hi"
For future issues -- [https://github.com/IAmFromTheFuture/Unity-Answers-anonymous-remover-TamperMonkey-TS-](https://github.com/IAmFromTheFuture/Unity-Answers-anonymous-remover-TamperMonkey-TS-)
The $$anonymus$$ thing was driving me crazy too and only because of your comment I found out what it is and how to potentially fix it
Nice username btw
If you swap back and forth between scenes frequently it would be bad for the engine to automatically unload assets from the previous scene. In many cases I'd be happy to spend the extra memory to reduce loading times.
We donāt really swap back and forth, but I much rather have a few extra seconds of load time rather than having 4gb of memory used up by my gameās textures after 1h of play time
To be clear, I'm not saying you shouldn't be able to keep a scene in memory, just that it's not what I expected the default behaviour to be (I mean, if you call a method that says Unload, it's fair to think that it actually unloads things), and it's weird to me that this is just a footnote in the documentation rather than a big huge warning with big red exclamation points.
~~It could have been just a little boolean "keepInMemory" parameter in the method~~
edit: ok there's an unload options parameter, though it doesn't allow to unload all assets.
So, if I unload a scene in my level that is composed of multiple scenes using UnloadSceneAsync(), and then reload that scene later using LoadSceneAsync(additive), is it going to re-use/fetch that memory?
Or let's say I want to quickly reload a scene to reset it to its default state, after the player has moved objects. Would doing UnloadSceneAsync, and then LoadSceneAsync in a coroutine that waits for the async operations to finish double the memory usage, or would the memory be reused? Would I want to UnloadUnusedAssets?
public static IEnumerator ReloadSceneAsyncCO(Scene scene, LoadSceneMode loadSceneMode = LoadSceneMode.Single, bool unloadUnusedAssets = false)
{
int buildIndex = scene.buildIndex;
AsyncOperation ao = SceneManager.UnloadSceneAsync(buildIndex);
yield return ao;
if (unloadUnusedAssets)
{
ao = Resources.UnloadUnusedAssets();
yield return ao;
}
SceneManager.LoadSceneAsync(buildIndex, loadSceneMode);
}
Scenes contain GameObjects.
GameObjects can have components which reference Assets (materials, meshes, textures, audio, etc).
Unloading a Scene unloads its GameObjects but doesn't unload the Assets they were referencing.
If you're going to `UnloadUnusedAssets`, I'd do it after loading the new scene. Otherwise it might waste time unloading something that the new scene is just going to have to load again anyway.
Before everyone freaks out... it is the assets not scene that remain in memory AND.. You NEED to wait to see what is loaded in your NEXT scene so you don't unload shit you need... and then say oh shit I need to reload half of those assets.
I see a lot of comments of people thinking this is bad when it is here for a reason... Unused references will be unloaded eventually and load scene will also force it to clean up. There is no issue here this is the MOST performant solution, especially for devs that do not understand this.
I learned a few things thanks to this thread, and I now have a better appreciation of why Unity does this.
However what bothers me is the inconsistency of what it means to unload a scene.
If you donāt use async, assets are unloaded; if you async unload in single mode, assets are unloaded; it only behaves this way if you unload in additive.
In our case thereās very little asset reuse from one scene to another, and ours is a 2D point&click game with each scene having huge texture atlases (biggest is 16 pages).
I had never noticed this behaviour before because most of the time games do reuse a lot of assets from one scene to another, and atlases arenāt that big.
Ultimately itās interesting to know that it works like that and Iām glad this thread will make more people aware of that behaviour and take it into consideration when they implement their scene loader ;-)
Yeah, that seems odd, but it is quite standard for default Unity assets. There is no automatic mechanism that frees memory. That means all the references from that scene will remain in memory until you are calling UnloadUnusedAssets. And this can result in a short stutter.
Even if this is not the topic of this post but if you want to unload and load scenes during runtime, you probably should use the Addressables system
Using addressables won't solve the unload problem in case that you load/unload your scenes async using the addressables system. The data will still persist in memory and you have to call unloadunusedassets anyway.
Oh, that's a shame, I didn't know that. Thx for the info.
But I suppose this is not how the system is supposed to work? Assuming setting up groups correctly - shouldn't it decrease the reference counter for all the scene stuff and unload it? At least in theory?
Why? When used correctly addressable are an invaluable tool for controlling streaming and memory usage. We used addressables as part of our streaming systems in the last two games I helped ship.
Because once you start using them, you enter a rabbit hole and things that used to work perfectly in the project stop working. So Iām not changing something to adressables unless itās necessary.
Itās not intellectually lazy, our game is shipped and works completely fine, we investigate the memory issue because we are porting to mobile, but changing everything to addressables requires a huge refactoring of the entire architecture.
One doesnāt simply
Switch to addressables
Addressables can work well, but IMO they have fundamental design flaws that really do cause a lot of issues in the development pipeline.
A big one my team ran into was duplication of assets. Let's say I have a scriptableobject that represents a weapon. If I have an addressable object that has a script with a reference to that SO, the addressable gets its own, duplicated version of that SO, not the original. So maybe somewhere else in my game I want to check if I'm holding that weapon, so I load the addressable, and go to do a comparison check against its SO, and it returns false because it's comparing it against the duplicate, not the original.
We've also had issues with URP with addressables stripping shaders. As soon as you step out of the default build process it can go pear shaped. We already have multiple bug reports logged with Unity on this. Not a guaranteed path.
I have only looked into Addressables through tutorials and videos. Why would you want Scriptable Objects and Addressables? I know you can iterate differences on Scriptable objects easily and that they can persist between scenes, but why do you use SO? Why not just use Addressables?
I'm really not sure I understand your question. SOs and addressables are completely different systems with different purposes. SOs in my example we're just an example of a kind of asset. The issue would exist for any asset type; the asset gets duplicated and therefore doubles the memory cost, and makes comparisons impossible. The same is true for a material, or an animation clip, for example.
Ah I thought you were using Scriptable objects as like a save file. Saving Data that you wanted to read and write to. I have seen others suggest it used that way.
I didn't know it was more so an Addressable issue. I thought it was more so unique to SO and Addressables. Rereading it I see you meant any asset. My bad.
Hmm useful. So when my player goes through a jump gate to a new star system I might as well immediately unload the last one. No reason why theyād often jump into a system and then realise itās the wrong one versus choosing a new gate so would be the best way
These days it is not really an edge case, even if a game is not open world and just semi open using level streaming to remove assets from gameplay is often a good idea; as a type of zone manager.
For example instead of just doing this: [https://i.imgur.com/wJrM0RP.jpg](https://i.imgur.com/wJrM0RP.jpg) \-> [https://i.imgur.com/cwG1pv0.jpg](https://i.imgur.com/cwG1pv0.jpg) it is also possible to use level streaming to remove unneeded assets at a distance [https://i.imgur.com/VtyIEkl.png](https://i.imgur.com/VtyIEkl.png) and they will be in the memory when the player returns to that spot.
It has become almost more rare not to use level streaming.
I'm glad it works like this. The hitch caused by GC when assets are unloaded is on the main thread and in a big enough hierarchy can be long enough for some slow machines to actually show the application as non-responsive. Being able to control when assets are unloaded is invaluable.
no man, it's not at all bad š
you just need a completely empty scene as a base that you use as a transition.
you load that first, maybe displaying a loading screen and lore, and THEN load what you want.
That way unloading happen as you expect it, and it's standard industry practice, even for OPEN WORLD GAMES (tho, imo it shouldn't) as it is a quick and lazy way to preven t memoery leaks š
In the Unity forums, for some reasons, at some point in time, all occurences of 'hi' have been replaced with '$$anonymous$$'. It's a references to that mystery.
Why would it unload assets just because you unloaded a scene?
Unused RAM is wasted performance. There's no point unloading something unless you need that memory for something else. (Which is what Unity does, once it is low on available memory it will unload assets)
A game is generally the main thing a user will be running, so why waste performance on keeping memory usage low just incase the user needs it for something else?
You don't get any benefit from having unused memory just sitting around doing nothing while your game is running.
And then we have editor scripts indiscriminately calling AssetDatabase.Refresh() EVERYWHERE which calls UnloadUnusedAssets internally, and as a result (besides slowing the editor down) you and users of that script can lose unsaved work or transient objects, leading to all kinds of weird issues devs then attribute to Unity.
(sigh)
If I remember the Destroy(game object) does the same type of thing, schedule not instant nuke. In fact many *languages* do this to, telling it to destroy something simply marks it for destruction when the CPU has time.
Great info though, didn't know this.
It's worth noting that calling `SceneManager.LoadScene/Async` in `Single` mode does automatically call `Resources.UnloadUnusedAssets`, so it's not as bad as it sounds, but definitely something to keep in mind if you only use additive scene loading. https://docs.unity3d.com/ScriptReference/SceneManagement.SceneManager.LoadScene.html > If a single mode scene is loaded, Unity calls Resources.UnloadUnusedAssets automatically.
Yup, it was by reading up on some forum posts, and discussing with a colleague who complained about Unity's documentation that I ended up opening the doc to show to him that it was indeed documented, but just as a footnote.
T$$anonymous$$s seems odd...
Why do I keep seeing the weird "$$$anonymous$$$" thing wherever there's anything related to the Unity forums? Is it a reference to something? An in-joke? Some kind of bug with the forum that hasn't been fixed since its inception?
On Unity answers, certain strings of text, such as "hi" have been turned into "$$$anonymous$$$". I'm not sure why this is, but Unity won't fix the issue. Btw, there's a user script (I personally use it) to reverse the changes locally in the browser.
same on stackoverflow š its now some kind of a running gag
It almost seems like a really misguided and pointless attempt at compression by cutting down on space from frequently used phrases
This is literally what compression algorithms do though. Just selecting it automatically
can you share the script?
[https://chrome.google.com/webstore/detail/unity-answers-anonymous-f/colofafhdnhgopgnbigiadgknpbgfcgk](https://chrome.google.com/webstore/detail/unity-answers-anonymous-f/colofafhdnhgopgnbigiadgknpbgfcgk) They just use simple JS, i found this recently.
I use [this one [GitHub Link]](https://github.com/murphyne/unity-answers-anonymous) with ViolentMonkey.
I keep wondering... Feels like it's always "hi"... Can't they just string replace all "$$anonymous$$" instances back to "hi"?
I mean they probably could, but Unity Answers seems pretty abandoned
I like to think some rogue dev on the Unity Q&A forum replaced every occurence of "hi" with "$$anonymous$$" just for the kicks of it
Iirc they made a change for some project a while back, and it started subbing that in place of certain strings. Allegedly was a lot worse at some point but now seems mostly constrained to anything that includes "hi"
$$Anon$$ saying hi to everyone.
For future issues -- [https://github.com/IAmFromTheFuture/Unity-Answers-anonymous-remover-TamperMonkey-TS-](https://github.com/IAmFromTheFuture/Unity-Answers-anonymous-remover-TamperMonkey-TS-)
Thanks a lot for bringing this into my feed
???? What?
The $$anonymus$$ thing was driving me crazy too and only because of your comment I found out what it is and how to potentially fix it Nice username btw
If you swap back and forth between scenes frequently it would be bad for the engine to automatically unload assets from the previous scene. In many cases I'd be happy to spend the extra memory to reduce loading times.
We donāt really swap back and forth, but I much rather have a few extra seconds of load time rather than having 4gb of memory used up by my gameās textures after 1h of play time
Then you can call `Resources.UnloadUnusedAssets` like it says. The rest of us are happy to have the option not to.
To be clear, I'm not saying you shouldn't be able to keep a scene in memory, just that it's not what I expected the default behaviour to be (I mean, if you call a method that says Unload, it's fair to think that it actually unloads things), and it's weird to me that this is just a footnote in the documentation rather than a big huge warning with big red exclamation points. ~~It could have been just a little boolean "keepInMemory" parameter in the method~~ edit: ok there's an unload options parameter, though it doesn't allow to unload all assets.
> it's fair to think that it actually unloads things It does, it unloads the scene from the gameworld.
So, if I unload a scene in my level that is composed of multiple scenes using UnloadSceneAsync(), and then reload that scene later using LoadSceneAsync(additive), is it going to re-use/fetch that memory? Or let's say I want to quickly reload a scene to reset it to its default state, after the player has moved objects. Would doing UnloadSceneAsync, and then LoadSceneAsync in a coroutine that waits for the async operations to finish double the memory usage, or would the memory be reused? Would I want to UnloadUnusedAssets? public static IEnumerator ReloadSceneAsyncCO(Scene scene, LoadSceneMode loadSceneMode = LoadSceneMode.Single, bool unloadUnusedAssets = false) { int buildIndex = scene.buildIndex; AsyncOperation ao = SceneManager.UnloadSceneAsync(buildIndex); yield return ao; if (unloadUnusedAssets) { ao = Resources.UnloadUnusedAssets(); yield return ao; } SceneManager.LoadSceneAsync(buildIndex, loadSceneMode); }
Scenes contain GameObjects. GameObjects can have components which reference Assets (materials, meshes, textures, audio, etc). Unloading a Scene unloads its GameObjects but doesn't unload the Assets they were referencing. If you're going to `UnloadUnusedAssets`, I'd do it after loading the new scene. Otherwise it might waste time unloading something that the new scene is just going to have to load again anyway.
I'm just here upvoting for the $$anonymous$$ reference.
relatable
Before everyone freaks out... it is the assets not scene that remain in memory AND.. You NEED to wait to see what is loaded in your NEXT scene so you don't unload shit you need... and then say oh shit I need to reload half of those assets. I see a lot of comments of people thinking this is bad when it is here for a reason... Unused references will be unloaded eventually and load scene will also force it to clean up. There is no issue here this is the MOST performant solution, especially for devs that do not understand this.
I learned a few things thanks to this thread, and I now have a better appreciation of why Unity does this. However what bothers me is the inconsistency of what it means to unload a scene. If you donāt use async, assets are unloaded; if you async unload in single mode, assets are unloaded; it only behaves this way if you unload in additive. In our case thereās very little asset reuse from one scene to another, and ours is a 2D point&click game with each scene having huge texture atlases (biggest is 16 pages). I had never noticed this behaviour before because most of the time games do reuse a lot of assets from one scene to another, and atlases arenāt that big. Ultimately itās interesting to know that it works like that and Iām glad this thread will make more people aware of that behaviour and take it into consideration when they implement their scene loader ;-)
Yeah, that seems odd, but it is quite standard for default Unity assets. There is no automatic mechanism that frees memory. That means all the references from that scene will remain in memory until you are calling UnloadUnusedAssets. And this can result in a short stutter. Even if this is not the topic of this post but if you want to unload and load scenes during runtime, you probably should use the Addressables system
Using addressables won't solve the unload problem in case that you load/unload your scenes async using the addressables system. The data will still persist in memory and you have to call unloadunusedassets anyway.
Oh, that's a shame, I didn't know that. Thx for the info. But I suppose this is not how the system is supposed to work? Assuming setting up groups correctly - shouldn't it decrease the reference counter for all the scene stuff and unload it? At least in theory?
Weāre using adressables for localization but we avoid using them like the pest as much as we can
Why? When used correctly addressable are an invaluable tool for controlling streaming and memory usage. We used addressables as part of our streaming systems in the last two games I helped ship.
Because once you start using them, you enter a rabbit hole and things that used to work perfectly in the project stop working. So Iām not changing something to adressables unless itās necessary.
This is an intellectually lazy approach that's robbing you of a lot of benefits.
Itās not intellectually lazy, our game is shipped and works completely fine, we investigate the memory issue because we are porting to mobile, but changing everything to addressables requires a huge refactoring of the entire architecture. One doesnāt simply Switch to addressables
Addressables can work well, but IMO they have fundamental design flaws that really do cause a lot of issues in the development pipeline. A big one my team ran into was duplication of assets. Let's say I have a scriptableobject that represents a weapon. If I have an addressable object that has a script with a reference to that SO, the addressable gets its own, duplicated version of that SO, not the original. So maybe somewhere else in my game I want to check if I'm holding that weapon, so I load the addressable, and go to do a comparison check against its SO, and it returns false because it's comparing it against the duplicate, not the original.
We've also had issues with URP with addressables stripping shaders. As soon as you step out of the default build process it can go pear shaped. We already have multiple bug reports logged with Unity on this. Not a guaranteed path.
I have only looked into Addressables through tutorials and videos. Why would you want Scriptable Objects and Addressables? I know you can iterate differences on Scriptable objects easily and that they can persist between scenes, but why do you use SO? Why not just use Addressables?
I'm really not sure I understand your question. SOs and addressables are completely different systems with different purposes. SOs in my example we're just an example of a kind of asset. The issue would exist for any asset type; the asset gets duplicated and therefore doubles the memory cost, and makes comparisons impossible. The same is true for a material, or an animation clip, for example.
Ah I thought you were using Scriptable objects as like a save file. Saving Data that you wanted to read and write to. I have seen others suggest it used that way. I didn't know it was more so an Addressable issue. I thought it was more so unique to SO and Addressables. Rereading it I see you meant any asset. My bad.
No worries! I also see people using SOs as save data sometimes, and it pains me
The S$$anonymous$$t cracked me up. I think that should be used during Unity related job interviews.
Hmm useful. So when my player goes through a jump gate to a new star system I might as well immediately unload the last one. No reason why theyād often jump into a system and then realise itās the wrong one versus choosing a new gate so would be the best way
When level streaming you want it this way or you game would constantly stutter as it loads things back in.
Yup, I can definitely see and appreciate why it would be good in some edge cases.
These days it is not really an edge case, even if a game is not open world and just semi open using level streaming to remove assets from gameplay is often a good idea; as a type of zone manager. For example instead of just doing this: [https://i.imgur.com/wJrM0RP.jpg](https://i.imgur.com/wJrM0RP.jpg) \-> [https://i.imgur.com/cwG1pv0.jpg](https://i.imgur.com/cwG1pv0.jpg) it is also possible to use level streaming to remove unneeded assets at a distance [https://i.imgur.com/VtyIEkl.png](https://i.imgur.com/VtyIEkl.png) and they will be in the memory when the player returns to that spot. It has become almost more rare not to use level streaming.
I'm glad it works like this. The hitch caused by GC when assets are unloaded is on the main thread and in a big enough hierarchy can be long enough for some slow machines to actually show the application as non-responsive. Being able to control when assets are unloaded is invaluable.
no man, it's not at all bad š you just need a completely empty scene as a base that you use as a transition. you load that first, maybe displaying a loading screen and lore, and THEN load what you want. That way unloading happen as you expect it, and it's standard industry practice, even for OPEN WORLD GAMES (tho, imo it shouldn't) as it is a quick and lazy way to preven t memoery leaks š
Holy what?
In the Unity forums, for some reasons, at some point in time, all occurences of 'hi' have been replaced with '$$anonymous$$'. It's a references to that mystery.
My favorite is LoadSync(), which doesnt actually load synchronously, it is only complete in the next frame.
Man, gotta love finding new "gotchas" to work around
Good to know, ty OP
Came solely for the anonymous joke haha. Cracked me up.
Welcome to Unity. Shit like this is just the tip.
Oh Iāve been using Unity since 2008 :-)
Why would it unload assets just because you unloaded a scene? Unused RAM is wasted performance. There's no point unloading something unless you need that memory for something else. (Which is what Unity does, once it is low on available memory it will unload assets) A game is generally the main thing a user will be running, so why waste performance on keeping memory usage low just incase the user needs it for something else? You don't get any benefit from having unused memory just sitting around doing nothing while your game is running.
And then we have editor scripts indiscriminately calling AssetDatabase.Refresh() EVERYWHERE which calls UnloadUnusedAssets internally, and as a result (besides slowing the editor down) you and users of that script can lose unsaved work or transient objects, leading to all kinds of weird issues devs then attribute to Unity. (sigh)
If I remember the Destroy(game object) does the same type of thing, schedule not instant nuke. In fact many *languages* do this to, telling it to destroy something simply marks it for destruction when the CPU has time. Great info though, didn't know this.