Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 13 Next capture
2021 2022 2023
1 capture
13 Jun 22 - 13 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
0
Question by Befall · May 01, 2012 at 08:17 PM · prefabresourcesefficiency

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!

Comment
Add comment
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

3 Replies

· Add your reply
  • Sort: 
avatar image
4
Best Answer

Answer by dannyskim · May 01, 2012 at 09:46 PM

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.

Comment
Add comment · Show 7 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image Befall · May 02, 2012 at 02:18 AM 0
Share

Can you elaborate on not how they're stored, because I understand the concepts behind sprite sheets, but how it is actually displayed? Does it use orthographic projection onto the camera, or what?

Just curious, and thank you so much for the response. $$anonymous$$ay have to consider this. :)

avatar image syclamoth · May 02, 2012 at 02:21 AM 1
Share

It draws the texures directly to the screen, bypassing the camera. Basically, Unity's inbuilt GUI system isn't very good (in general), not least because it has no texture atlassing capabilities whatsoever...

Little anecdote about UnityGUI- I'm currently working on a TD game, and at one point I wanted to display a little bit of debug info above my creeps for some reason. I figured, the simplest way was to just put an OnGUI function on the creep, and draw stuff with that (quick, easy, right?). Turns out, that simply putting an empty OnGUI function in my Creep script, for even a reasonable number of creeps (<200) sent my framerate down by almost a factor of 5. It's really, really not worth it in almost all situations- you'd be best served to just write your own (or if you're happy to fork the money out for them, using one of the many 'advanced UI' packages out there on the Asset Store).

avatar image Eric5h5 · May 02, 2012 at 02:36 AM 1
Share

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 )

That's not true at all. A project with two GUI textures, 40x64 and 24x64, uses 12.2$$anonymous$$B in the build for textures, whereas a project with one GUI texture, 64x64, uses 12.1$$anonymous$$B in the build. (As to why there's any difference at all, I would assume because of extra overhead with more than one texture, even if the number of pixels is the same.)

avatar image syclamoth · May 02, 2012 at 02:40 AM 0
Share

Yes, in the build they take up that much space, but as soon as they get loaded into the graphics card you still have the same problem. I'm not aware of any common graphics cards that support NPOT textures.

avatar image Eric5h5 · May 02, 2012 at 02:57 AM 1
Share

As far as I know, most modern graphics card do NPOT; the main reason not to (at least in the past) was because of mipmapping, which you're not using with GUITextures anyway.

Show more comments
avatar image
1

Answer by Eric5h5 · May 02, 2012 at 02:51 AM

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.

Comment
Add comment · Show 3 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image Befall · May 02, 2012 at 04:51 AM 0
Share

First off, I'm confused by that; one project would have a texture, the other would have a texture AND a prefab. How would it possibly be smaller?

So you would suggest making everything public, and should I make prefabs first or drag'n'drop textures in?

avatar image syclamoth · May 02, 2012 at 04:56 AM 1
Share

It's smaller because the project with just the texture has more code for generating the object at runtime! Prefabs basically do this already, keep in $$anonymous$$d, except that the code for generating the objects at runtime already exists in the engine, and so not using it only creates unneeded overhead (since you can't avoid including the whole UnityEngine dll in your builds).

avatar image Eric5h5 · May 03, 2012 at 03:39 AM 1
Share

I doubt a prefab takes more than a few bytes or so. The code needed to generate the same thing that's in a prefab is more expensive than just using a prefab.

avatar image
0

Answer by Comaleaf · May 01, 2012 at 09:52 PM

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 rather than GUI objects, you won't need to use prefabs at all.

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

Comment
Add comment · Show 2 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image dannyskim · May 01, 2012 at 09:57 PM 0
Share

If you're worried about performance along with your package size, I would suggest not using UnityGUI (OnGUI, which GUI.DrawTexture resides).

GUI.Repaint is utterly resource intensive on a mobile device, and will slow things down ultimately. If this is a purely UI based application, I would say you could go for it, but if the GUI resides anywhere in parallel with gameplay, do not use it.

avatar image Comaleaf · May 01, 2012 at 10:17 PM 0
Share

Thanks @dannyskim - I did not know about that! $$anonymous$$ay have to now redo a lot of GUI on my own project... I've updated my answer.

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

6 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

Prefabs are instantiated in editor but not in executable 2 Answers

Eliminating prefabs from resources folder? 1 Answer

Best method to save states in/for a prefab 0 Answers

How to avoid storing the same resource for each gameobject? 1 Answer

How to know if a GameObject is a prefab? 15 Answers


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges