2D Toolkit Forum

2D Toolkit => Support => Topic started by: Dajuice on March 01, 2013, 02:06:36 pm

Title: Sprites, Atlases and memory management
Post by: Dajuice on March 01, 2013, 02:06:36 pm
I'll start off by telling you I'd find it normal and not rude at all if you don't answer this but since I don't know where to begin, I'm taking as many paths as possible to get my answers.

I've been making my first unity game for almost 5 months now and you did a great job guiding me through hardships, thanks.
But now I've discovered that (on IOS at least) the profiler is completely irrelevant, or that I'm doing something very wrong, I'm asking you this to make sure I'm not doing something wrong.
The game we're making is really texture heavy (we have over 30 jam packed atlases, most of 'em 1024x1024), at the title screen, the unity profiler tells me it uses about 20MB, the Instruments profiler tells me 90MB. What I understand from that, is that the unity profiler hides the textures that are currently used but not on screen from the memory profiler. This means that the unity profiler tells me that only the title screen is in memory and my other textures are somehow compressed, ready to be used, but in fact my whole UI is loaded with all it's textures fully uncompressed.

So this is it, is there some mojo I must do in order to make the iOS behave just as the unity profiler tells me it behaves, or must I manually manage all those atlases?
Title: Re: Sprites, Atlases and memory management
Post by: unikronsoftware on March 01, 2013, 04:14:10 pm
How do you load these unused atlases?
Do you have references to these in your game?
Title: Re: Sprites, Atlases and memory management
Post by: Dajuice on March 01, 2013, 04:28:20 pm
They are in the scene, my situation is much like the one from this post http://unikronsoftware.com/2dtoolkit/forum/index.php/topic,1129.msg5377.html#msg5377 (http://unikronsoftware.com/2dtoolkit/forum/index.php/topic,1129.msg5377.html#msg5377).
I'm loading my UI scene and accessing it and all, but when I was profiling with unity it told me that everything was fine and all was finely handled (when I see the title screen, the textures memory takes the space of my title atlas, when I am in my shop, the texture memory takes only the space of my shop atlases and so on...) but it seems that no.  so I guess I'll have to make my memory management for this, I think I have an idea: serialize and destroy the sprite components when they are hidden, then re-add them to next shown assets when making a page to page transition.

I know that in your previous post, you advised to load all the UI then only take what's important then dump everything else, but I feel like much of the loading time would be a waste of load unused and delete unused assets... So you think it could be done my way?
Title: Re: Sprites, Atlases and memory management
Post by: Dajuice on March 01, 2013, 08:58:00 pm
Further research on how to do what I want to do led me to this topic: http://unikronsoftware.com/2dtoolkit/forum/index.php/topic,1058.msg5098.html#msg5098 (http://unikronsoftware.com/2dtoolkit/forum/index.php/topic,1058.msg5098.html#msg5098)
this has been really helpful, but you told the poster "But, if all you want is to load sprite collections dynamically, you don't need to do this. I'll reply to your email soon with more details about that, just held up with some stuff right now. It does work." And I believe that the content of this email replay is the answer I need.
Title: Re: Sprites, Atlases and memory management
Post by: Dajuice on March 01, 2013, 09:23:20 pm
haha, okay I'm sorry for the unnessessary reading.. I'll just say that I found the docs about Loadable asset and now I'm theorically able to load collections... BUT... when I press the loadable asset check box, it loads a little bit, then the box remains unchecked, and I'm still unable to load the collection with :
Code: [Select]
tk2dSpriteCollectionData col = tk2dSystem.LoadResourceByGUID<tk2dSpriteCollectionData>(colName);
Title: Re: Sprites, Atlases and memory management
Post by: unikronsoftware on March 02, 2013, 03:11:10 pm
You should be able to use "Loadable assets", it isn't a public part of the toolkit, but it does indeed work. What version of tk2d are you running? There was an issue in older versions where manually creating loadable assets didn't work properly.
Title: Re: Sprites, Atlases and memory management
Post by: Dajuice on March 04, 2013, 02:06:49 pm
hmm... I'm a little screwed as I was using clipped sprites, now they're an incompatibility hive.. I'll try to repair the lost connections.
Title: Re: Sprites, Atlases and memory management
Post by: Dajuice on March 04, 2013, 02:08:38 pm
ok, I shouldn't post before even trying, done, it is just your new way to access Collections from outer classes that was giving me those error messages
Title: Re: Sprites, Atlases and memory management
Post by: Dajuice on March 04, 2013, 02:33:50 pm
And now I'm stuck just a little further: The checkbox checks, I have the loadable asset path/name, but when I try to access it with the command line, it returns nothing, before it was Null, now it is nothing.. Here is a picture that explains what I did, is there anything I did wrong?http://d.pr/i/opay (http://d.pr/i/opay)
Title: Re: Sprites, Atlases and memory management
Post by: Dajuice on March 04, 2013, 02:43:35 pm
And yet again, I find 3 minutes to late... but this time I,ve been misled! In your doc http://www.unikronsoftware.com/2dtoolkit/doc/reference/sprite_collection.html (http://www.unikronsoftware.com/2dtoolkit/doc/reference/sprite_collection.html)
you use tk2dSystem.LoadResourceByGUID<tk2dSpriteCollectionData>, but it seems to work fine using tk2dSystem.LoadResourceByName<tk2dSpriteCollectionData>, maybe you would want to update the docs? I know I'm a hell of a fool proof test, but ... there is no but, just thanks.
Title: Re: Sprites, Atlases and memory management
Post by: unikronsoftware on March 04, 2013, 02:47:15 pm
Yup I should update the docs :)
That is a typo on my part. Sorry for the confusion.
Title: Re: Sprites, Atlases and memory management
Post by: unikronsoftware on March 04, 2013, 02:49:59 pm
Updated the docs.
Title: Re: Sprites, Atlases and memory management
Post by: Grebenots on April 24, 2013, 12:59:36 am
Is there any functionality to unload a sprite collection/atlas manually?
Title: Re: Sprites, Atlases and memory management
Post by: unikronsoftware on April 24, 2013, 10:32:32 am
There will be a explicit way to unload a specific sprite collection in 2D Toolkit 2.0.

For now, if you destroy all sprites using the sprite collection, and then do Resources.UnloadUnusedAssets(); that should unload all unused spritecollections.
Title: Re: Sprites, Atlases and memory management
Post by: Grebenots on April 24, 2013, 02:53:04 pm
In my case, I have just 1 sprite that is being used to display one of the 300 or so tiles(from 6 or so collections).  Would changing this sprite's collection and spriteid, then unloading the unused assets, work the same way?
Title: Re: Sprites, Atlases and memory management
Post by: unikronsoftware on April 24, 2013, 03:26:39 pm
Yes. It should work as long as there are absolutely no references to the sprites / materials or textures left.
Title: Re: Sprites, Atlases and memory management
Post by: Grebenots on April 24, 2013, 03:58:49 pm
Good to know!
One last thing.  Does merely having a tk2dSpriteCollectionData variable in the inspector actually load the sprite collection into memory?

For instance,

My single sprite has,

var myColorCollection : tk2dSpriteCollectionData;
var myAnimalCollection : tk2dSpriteCollectionData;
etc etc.

However, this single sprite only ever has any one of those collections loaded at any given time.  Will this keep only the active collection in memory so long as I unload unused assets, or does having those variables gum things up?
Title: Re: Sprites, Atlases and memory management
Post by: unikronsoftware on April 24, 2013, 04:03:00 pm
Yes. You should load using Resources.Load if you wish to dynamically swap stuff.
Title: Re: Sprites, Atlases and memory management
Post by: Grebenots on April 24, 2013, 05:12:20 pm
Making some progress here, however:

When I use , mySpriteCollectionData = tk2dSystem.LoadResourceByName<tk2dSpriteCollectionData>("ColorTiles");

I get the error:

Cannot infer generic arguments for method 'tk2dSystem.LoadResourcesByName.<T>(String)'.  Provide stronger type information through arguments, or explicitly state the generic arguements.

I'm not sure what that means.  Loadable asset is ticked and committed in the sprite collection as well.
Title: Re: Sprites, Atlases and memory management
Post by: Grebenots on April 24, 2013, 06:24:37 pm
At any rate, it's not a big deal.  I have a standard Resources.Load working fine.
Title: Re: Sprites, Atlases and memory management
Post by: unikronsoftware on April 24, 2013, 11:37:58 pm
That is quite bizzare.
What type is mySpriteCollectionData? I trust it is a tk2dSpriteCollectionData and not a var?

The GUID variant is used just like this, and I take it you're not getting any errors about that?
platformSpecificData = tk2dSystem.LoadResourceByGUID<tk2dSpriteCollectionData>(guid);
Title: Re: Sprites, Atlases and memory management
Post by: fattie on September 11, 2013, 12:26:43 pm
"There will be a explicit way to unload a specific sprite collection in 2D Toolkit 2.0."

So to be perfectly clear, this is ..

http://unikronsoftware.com/2dtoolkit/forum/index.php?topic=2101.0

scroll down to the example "scdToUnload.UnloadTextures()" ..

am I correct?

Where's my best bet for any doco or examples on this?  Cheers
Title: Re: Sprites, Atlases and memory management
Post by: unikronsoftware on September 11, 2013, 01:07:14 pm
UnloadTextures is it. It definitely works, but you need that funky reload trick to load things back in. Thats sadly a Unity bug.
Title: Re: Sprites, Atlases and memory management
Post by: fattie on September 15, 2013, 02:37:26 pm
"For now, if you destroy all sprites using the sprite collection, and then do Resources.UnloadUnusedAssets(); that should unload all unused spritecollections."

One finding, based on a tremendous amount of testing on a vast number of iOS devices from 3GS onwards.  I have found that it DOES IN FACT (i.e., Unity does in fact), CORRECTLY get rid of the memory from texture memory, when you use TK's UnloadTextures.

This is great news.

(Typically you can not really use UnloadUnusedAssets during gameplay, as it is slooow of course in Unity. So normally that's not really an option, I'd say.)

So in short I have found that the UnloadTextures approach works really well, perfectly - you can sit there watching the texture memory go up and down - absolutely reliably - in the profiler.  (This on iOS anyways - who knows on android!)

-- HOWEVER --: I have found, furthermore, that if you are running up against the memory limit in iOS, "you're screwed".  Say you unload collection "AA".  The problem is this: later, you want to load "AA" again, unity WILL NOT DO IT - essentially a bug or weakness in Unity. (Unity should, at worst, stop everything and do a slow UnloadUnusedAssets and load your new request for you, but it doesn't, you're screwed.) Again this is only when you're getting memory warnings in iOS.  But it's a killer problem because instead of your textures you'll get - black.  :)  (Annoyingly in a way, Unity, I think generally, sort of magics most memory warnings in iOS and does its very best to keep going anyway, that's great but you can get a bit sloppy about texture memory usage when developing for iOS with Unity.)

So anyway, I have found with vast testing that UnloadUnusedAssets works really fantastically, it works perfectly. You can load the collection later again when you need it.

Certainly, any time you have "backgrounds" on a 2D game, this would basically be a must, you could only work this way (you couldn't leave different backgrounds, which are enormous on retina, and relatively enormous even on old phones, hanging around).

I use precisely this code ..

Code: [Select]
function __specialReleaseTechnique( ccc:tk2dSpriteCollectionData )
{
var mtl:Material;
for ( mtl in ccc.inst.materials )
{
Resources.UnloadAsset( mtl.mainTexture );
}
}