One of the coding things that seems easiest to trip up on in Unity is the leaving behind in memory of Unity Objects - textures, meshes etc. that no longer need to be there, but since you have not called Destroy on them or Resources.UnloadUnusedAssets() they are still around.
Of course this goes entirely against C# and garbage collection… many people are not even aware of how unity Objects operate…
but does anyone have any classes/patterns they use to make sure to track usage?
I am not sure why there is not some auto reference-counting system
I’m also not sure this subject is well covered in the docs!
An “auto reference counting system” is basically garbage collection. However, if you dont destroy something, it still exists. And if it still exists, that might be (and usually is) intentional. So how would a system automatically remove something it cant know whether it’s still used or not?
Garbage collection can do that (expensively!) by checking if there is no reference to an object in memory anymore. It’s possible. Unity however basically always references things. If there is a script running, that’s referenced somewhere. If an object is getting rendered, that’s referenced somewhere. And even if none of that is the case and the object is disabled, it’s still part of the scene, so of course there is a reference to it.
So how, except by telling Unity directly, would Unity be able to differentiate between objects that seem inactive and are still needed, and objects that seem inactive and will never be used anymore?
If i’m completely missing your point here please say so.
I seem to never have these “leaving objects lying around” issues. Here are some basic patterns:
if you have a resource locator (or preloader or GameManager) mechanism that might keep static references, give it a Purge() method and call it from OnDisable()
switch scenes between major portions of your game
finally if you do allocate certain classes of assets at runtime and you are NOT changing scenes, be sure to Destroy() them… that’s just basic allocation / freeing.
It helps a lot if you remember that your code is NOT the app. Unity is the app. Unity gets first say over all UnityEngine.Object-derived objects. This means you must “play nice” and let Unity know so that it can destroy its own engine-side part of the object.
It is basic allocation / freeing, but that is what C# as a language avoids with gc (not that you want it running too often).
It is what I struggled with in c++ and was happy to leave behind! (though it has probably got much better in last decade).
But Unity engine is c++ underneath, so there we go…
Anyway - must improve my management of these assets, I do generate a lot in code.
If you don’t switch scenes but need a good purge between levels/etc. then Resources.UnloadUnusedAssets() is a good one!