Decreasing project size by eliminating prefabs and creating everything from code

Hey all,

I’ve noticed for a game I’m working on, which includes tons of GUITextures (iOS), I’ve ended up using a lot of prefabs in the Resources folder that are simply a GameObject with a GUITexture component.

In efforts to drastically reduce or completely eliminate all the prefabs in memory, I’ve taken to instantiating a new GameObject in code and adding any components, changing settings, etc. Is this more efficient? For example:

Originally, it’d be something like:

GameObject deathIconO;
GUITexture deathIcon;

void Start()
{
    deathIconO = Resources.Load("GUI/Icons/deathIconPrefab") as GameObject;
}

void Update()
{
    ...
    deathIcon = Instantiate(deathIconO.guiTexture) as GUITexture;
    ...
}

However, this meant for each GUITexture that went up, we’d have a texture in memory AND a prefab. Now, I’m doing:

Texture deathIconTex;
GUITexture deathIcon;

void Start()
{
    deathIconTex = Resources.Load("GUI/Icons/Texture/deathIconTexture") as Texture;
}

void Update()
{
    ...
    GameObject deathIconO = new GameObject();
    deathIconO.AddComponent<GUITexture>();
    deathIcon = deathIconO.guiTexture;
    deathIcon.texture = deathIconTex;
    // adjust size, pixel inset, transform options, etc...
    ...
}

The reason I bother to store the texture used for each icon in a private variable is because there are lots of menus opened all the time, so it saves a call to Resources.Load every time you open each menu.

Is this more efficient? This way, for each icon we only have NO prefabs in the project, just textures (which were there before). Just curious if this would make sense. Thanks for any input!

It won’t help much at all. If you take a look at the Console Editor Log ( ‘Open Editor Log’ button on the Console Window ), you’ll be able to see what exactly your package is comprised off before it hits XCode after you build. Prefabs taking more space than your textures is pretty much not going to be the case 99.9% of the time, nor will doing this have any appreciable effect on your package size.

Simply put, using GUITextures is fairly inefficient in regards to package size. Standard practice in the gaming industry ( and even application design when heavy on UI ) is to atlas your textures ( aka sprite sheet, altas sheet ). At first, most people may think how will combining textures into one bigger sheet help at all?

Well, if you’re making pixel perfect textures for your GUI ( which you should be ), then atlas’ing them becomes a much more efficient option because you can cram NPOT ( Non-Power of Two ) textures into an atlas, whereas you can’t do that with individual textures ( you can, but they take up approximately 4 times the space of a power of two texture ). In turn, the atlas sheet itself is generated as a POT( power of two ) texture, optimizing your texture sizes by utilizing as much space as possible without wasting memory.

GUITextures is pretty much the most primitive form of GUI that I could possibly recommend using. Have I used them? Yes, but your package size will always suffer unless you design your GUI to be flexible and reusable ( such as sliced sprites, font atlases, etc).

In short, what you’re doing isn’t going to help at all. I would suggest getting a GUI plug-in such as NGUI ( available on the asset store ), or roll your own GUI system.

No, it’s not more efficient. You’re making things harder on yourself and your project worse for no gain. Why not just do a simple test? Make a test project with a GUITexture prefab, and then replace that with code to create a GUITexture, and compare the two builds. (Hint: the build without the prefab is actually larger.) Also in general I’d suggest using public variables with drag’n’drop instead of using Resources.Load, unless there’s a compelling reason not to.

Edit: Daniel Kim’s comment suggests you may want to avoid UnityGUI for performance reasons. Having done some cursory checking that does seem to be the case. My original answer is below, but keep the performance cost in mind. Some info here.


If you use [UnityGUI][2] rather than GUI objects, you won't need to use prefabs at all.

For drawing GUI textures, you can use GUI.DrawTexture.