Assets Usage: unity crashes because of too many Image Assets, how to deal with this?

I have an emergency here as I no longer can use unity and continue my project because of memory crashes. I am using an iMac with 4GB memory; as much as 2,3GB is available for Unity when nothing else is opened.

I don't have an impressive number of images in my project, but I need to display about 20 HD 1920 pictures and their low resolution versions. Only one at once, of course. This makes about 100 image assets in the library.

These images are to be used for base GUI aspect. Other GUI elements (buttons) are used with default Style or slight variants of default style.

I have understood so far that I need to use Texture2D variables.

I also had to set them to 2048x2048 texture size, as their real size is 1280, 1440, 1600 or 1920 width and more than 1024 height.

I am dissatisfied with image quality loss at any point (this is for the GUI, it needs to be perfect). I had to set them to RGBA 16 bits, with Kaiser mipmaps enabled to reduce the loss to something less noticeable.

Everything went rather smoothly - some quality problems excepted. So, I was always wondering: how can I just use my PNG image with full quality, as the original image, on GUI without having all this 3D texture-importing hassle? am I doing the right thing, or not?

Then, when I had to deal with some other resolutions to make things right, I encountered heavy memory problems. This comes to the point where I can no longer work on this commercial project. With 100 images, I do not think I am overloading memory this bad, but the point is that NPOT (Non Power of Two) textures eat memory badly.

So, I need big help here. The iMac cannot accept more than 4GB memory and actually, it has been said that even on a PC with 16GB, Unity can only use as much as 2-3GB anyway.

How can I optimize this memory usage? Will making all my images as 2048 per 2048 pics - a lot work also because of all the GUI scripts to adapt - can help enough?

Should I use Texture2D objects, or are there other solutions to this? (ie I do not think using the 3D cube instead would be a solution)

How can I have a PNG image with full quality and transparency, is there another way?

And should I load www-assets at runtime with local files as my target files, so that they could not be in Library?

My thanks to the community or Unity support for help on this problem.

You could put them in the resources folder and load them at runtime with Resources.Load, then when you're done with the image, destroy it using Object.Destroy, and use Resources.UnloadUnusedAssets (or maybe call it once every 2-3 images)

That way you only ever have one of those images in memory at once

http://unity3d.com/support/documentation/ScriptReference/Resources.html

After one day reworking the whole project and trying to find out how to deal with all this, I eventually made it. As I have seen several developers hitting memory problems at times, jere is the whole answer.

As an introduction to this solution, I want to point the fact that I wasn't exactly doing "bad things", that is, doing infinite loops or any kind of heavy scripts. For a long time, I absolutely had no problem with what I was doing, which was mostly like what everyone here does; the only difference with some people here being that my scripts were Javascript and not in C#.

My usage was very simple, but after some time with everything running smoothly, Unity Editor was beginning to hit the memory limit (around 2.4 GB for me) and to crash very often.

Here is what I was doing, which created the problem:

  • I imported my PNG images as Texture2D assets.

  • My assets were often NPOT (Non Power of Two) high resolution images,.

  • These assets were declared as member variables of my objects (to be able to drag&drop them into the object from the library, inside the Editor).

  • These variables were affected by default (ie. the picture was dragged over it inside the Editor)

  • There were around 30 such assets. At one time I decided to create an array of 18 of these assets. When I was dragging picture from the Assets library to the field, I noticed some slowdown, nothing more. This is exactly when Unity jumped from 0.4 GB memory to about 2.2 GB memory, without me noticing it.

As long as my Texture2D array was filled with the eighteen 1920 hi-res pictures, Unity was memory-mad.

  • Since Unity Editor was already eating up so much memory, everytime I tried to import a new picture Asset inside my Library, this was likely to make the Editor crash.

This sounds like a bug with Texture2D arrays in javascript, but I cannot be sure, I am still young to Unity.

Here is what I tried, which didn't exactly work:

  • I removed the settings of these variables (leaving them empty again). As soon as the Texture2D array was emptied, Unity came back to 0.4 GB memory consumed.

  • I was then able to add my other pictures inside my Asset library. Unity was able to insert them without going much above its regular 0.4 GB memory consumption.

  • Now that I was again able to use the Editor, I modified programs to use Resources.Load instead of setting my pics inside tons of Texture2D objects.

  • Again this failed: the Editor memory was fine, but when building, it tries to insert all these Assets and Unity fails again and crashes. Even with only one Asset used and only one line of Resources.Load(), Unity was crashing on the"Building level 0" step.

Maybe Unity was broken at this time. I don't know. It seemed that I was still bothered by memory problems because of the picture assets inside my Library.

I of course have tried to delete / reimport them, try other texture settings, to no result.

Here is the solution THAT worked:

Of course, if you never ran into this problems, you can continue the way you are doing things. Using Resources.Load() with picture assets inside your library is the right way to do things and avoid heavy memory usage, just as Mike underscored.

But it couldn't get me past my problem; it was the library that was memory-exploding in my issue. Even with my Texture2D as empty objects and only one Resources.Load() at the project start, project was broken and unbuildable.

I don't know how it came to do this; this may also be a PNG format problem for instance; I know that Photoshop CS4 did crazy things with my PNG files and broke them everytime, Corel Paintshop was used to fix the mess CS4 did.

So, I don't know this happened; I only know how I eventually got it fixed.

So, if you see the Editor using too much memory, experience Editor crashes, or are unable to build and run your program, here is what you maybe should check:

1. Don't load too many high resolution picture assets inside your library.

  1. Use Resources.Load() with picture assets inside your library as long as it seems fine.

  2. You may use dynamic resource loading, targeting local files, with the WWW object and file:// urls.

Note for MAC users: it took me some time to find out that to have the same thing as...

file://c:/...

You have to write things like:

file:///Users/Desktop/myUserName/...

Notice the three slashes.

There was no C drive on my iMac, I googled for a solution, but eventually found out by opening a local file with Safari.

Don't create Javascript Texture2D arrays as preset member variables, with heavy hi-res pictures in their rows. This seems to break up memory usage - at least it did with me.

So I worked things out by removing almost all picture assets from my Library, by placing them inside another folder out of the Assets folder, which relieved Unity Editor and Unity Builder.

I now access these resources with WWW-loading. I have about four Texture2D objects that get dynamically switched thanks to this.

This completely works.

I just don't know how things got broken, as of course, I suppose you are fine by using Resources.Load() yourself.

But hey, I am only doing many GUI screens and switching them, and if it happened to me, it may surely happen to someone else; so here at least you have a solution that could also work for you.

Just wanted to add that we've run into pretty much this same problem with building assets crashing Unity and this is with the recent Unity 3.x

Everything was going well, with having very little resident referenced assets in the scene and using a combination of Resources.Load() and Resources.UnloadUnusedAssets().

Until the Resources folder seems to get just too big or contain too much data. Then no matter what platform, PC, Mac or iPhone you try to build for it crashes on building.

We started to re-write to load via WWW (asset bundles), and whilst eventually we got this to work.. the Unity Editor crashes trying to output all the assets as a single bundle. So we tried splitting the assets across multiple bundles.. and this is better, but the editor eventually crashes after exporting 4 or 5 bundles. So to get this to work we need to export bundles 1-4, reboot Unity and then export bundles 5-8.

Thankfully, for now, we've found a way to dip the memory usage in the Resources folder down just enough to allow a build to work (we are back using Resources.Load()). But this isn't a good solution long term and if the memory usage peaks back too high again we'll have to resort to the pretty nasty asset bundles approach.

A very interesting thing that happens on both Mac & PC when building asset bundles is that the Editor memory allocated appears never get released, and eventually this appears to causes the Unity Editor to crash.

It would seem understandable for this to be a very similar process to when Unity automatically exports the 'Resources' folder as an internal data file (as an internal asset bundle perhaps?) and could then explain why the initial problem of "too many" assets in the 'Resources' folder occurs.

We are sure there is a memory leak bug in Unity's asset loading which is causing the problem.

We are going to try and inform Unity of this but I doubt it will be fixed in the short-term. The choices appear to still be (as of Jan 2011)..

1) Reduce texture resolutions & sizes within the Resources folder until you can build

or

2) Build resources into asset bundles (probably multiple or you'll get Editor crashes again) and load as local files via the WWW class.

WARNING: Note that if you are intending to build and deploy on iOS using method (2) you need to find out how to deploy your files into the right folder and use the correct file:/// path etc. which is yet another load of hassle.

Thankfully, this problem didn't de-rail us, but it nearly did. Think we wasted at least a couple of days on it.

Very annoying!