Some questions on Unity best practices

I’ve been dabbling with Unity for about a year now, and am putting together my first game. I have proof-of-concept projects completed, my pipeline for Unity-ZBrush-3DSMax-Photoshop all worked out and tested… basically after a year I am ready to take all I’ve learned and actually get this game completed. I’m turning to the community for a little guidance on some best practices to make sure I can get the most out of the Unity engine. Any help would be greatly appreciated. I realize the following points are pretty general in their nature, but I’m really just looking for advice on whether I could be doing things in a more practical (or efficient) way.

First, I like to load some of my textures via a WWW request. It works great, but I’m a little concerned with how I store them. I generally create an array of Texture2D’s and another array of booleans that keep track of whether that particular texture has been loaded already. Is this a terrible way of doing things? My arrays are generally one or two dimensions, with up to 10 elements in each.

I found an FPS script on here somewhere (code below) and added it to my game so I can easily view frame rates on my droid device. The odd thing is that this number is never anywhere near the FPS that the Unity Editor displays in the stats window… the stats window always shows an FPS that is about double what the script displays. From my experience with games, it seems as though the script is more accurate than the stats window, but I’m curious as to why this happens and how I can ensure that I am getting accurate FPS info in my game.

Code for FPS :

using UnityEngine;
using System.Collections;
 
public class HUDFPS : MonoBehaviour {
	 
	public  float updateInterval = 1.0F;
	public float fps = 0f;
	private float accum   = 0; // FPS accumulated over the interval
	private int   frames  = 0; // Frames drawn over the interval
	private float timeleft; // Left time for current interval
 
	void Start() {
	    timeleft = updateInterval;  
	}
	
	void OnGUI() {
		GUI.Label (new Rect(Screen.width - 110, 10, 100, 20), "FPS: "+fps, GetComponent<StyleGUI>().mainDataStyle);	
	}
 
	void Update() {
	    timeleft -= Time.deltaTime;
	    accum += Time.timeScale/Time.deltaTime;
	    ++frames;
	 
	    // Interval ended - update GUI text and start new interval
	    if( timeleft <= 0.0 ) {
	        // display two fractional digits (f2 format)
			fps = accum/frames;
			fps = (float)Mathf.RoundToInt(fps * 10) / 10;
		}
	}
}

Unity’s GUI system seems a bit strange, but I’ve read that there’s a big GUI update coming with the release of 4. Until then, I’m curious about the best practice for using GUIStyles and GUISkins. Which is less resource heavy? I prefer using a public GUIStyle on my scripts and adjusting them individually in the Inspector. I’ve also dabbled with creating a GUISkin, initiating a “copy” of that skin, and adjusting font sizes, colors, etc. from that point on, but the GUISkin just seems like it would be much more resource heavy. I know there are a lot of tutorials out there on the GUI system, but I have yet to find one that explains the best way of going about it and why it’s the best way.

I read in some forum posts that rather than using transform.do_something in your update functions, it is best to set a transform variable to the objects transform in the start function, and then use that variable in the update function. For example :

void Start() {
     _transform = transform;
}
void Update() {
     _transform.do_something;
}

I can see (from my inexperienced perspective) benefits for both. Storing the variable would improve response of the Update function itself, but then the variable has to be stored in memory the entire time the game is running, whether that _transform variable is getting called or not. The odd thing is that in all of my searching I haven’t come across many coding examples that use this, which makes me wonder whether it really is a best practice or not. Any input on this would be greatly appreciated, before I end up with 100 Update functions that are all using a _transform variable when they shouldn’t be.

Lastly, I would love to be able to load game objects via a WWW request the same way I do textures, but from what I’ve read this can only be done with Unity Pro. I have every intention of purchasing Pro in the future, but was just curious if there is a way to do it with the free version. If not, I’ll wait.

My apologies for numerous points in this post, but I figured it’d be better than clouding up Answers with several separate questions. I would really appreciate any advice/tips on this and anything else anyone has to offer. I am not looking for anyone to do the work for me by any means, just reaching out to the community of more seasoned Unity programmers for some direction on maximizing my games performance… at least as far as these points are concerned.

FPS

Your FPS calculator looks odd to me!

I would have thought that accum should be incremented by Time.deltaTime/Time.timeScale and then your fps calculation would be the more obvious frames/accum.

GUI

You don’t say what platform you are going to be building for - this does make a difference. Unity 4.? will contain the new GUI system, it looks very nice but Unity 4.0 will not have it and who knows when it will be released - soon I hope.

In the meantime if you are developing for mobile devices do not, under any circumstances use OnGUI. Buy NGUI or EZGUI and use that instead.

Texture Loading

Use a dictionary to keep an association between your textures URL and the loaded Texture2D.

 static Dictionary<string, Texture2D> textureCache = new Dictionary<string, Texture2D>();
...
Texture2D textureToUse;
if(!textureCache.TryGetValue(url, out textureToUse))
{
    textureToUse = //Load texture from WWW here;
    textureCache = textureToUse;
}

Keep your textures square/power of 2 sizes to save lots of memory. Compress them after loading if you want to.

Caching things

It makes a massive performance difference to cache things like transform. Do it. If you don’t see code using it then its just quickly knocked out stuff, the author isn’t aware of the penalty - or it isn’t being used often enough to make a difference. Caching transform etc takes 4 bytes for each one.

Also be very aware that setting and getting the .position and .rotation of an object is expensive - it has to walk all of the parents to work out what the local value should be. Either cache positions and rotations if you can or even better, use the localXXXX versions. So if a routine does _transform.position twice - stick it in a local variable, if a script totally owns the position of something then cache it in a variable in Start or Awake and only ever write it. As I mentioned before, using localPosition is better still because writing the value will not incur a penalty either.

Loading objects by WWW*

You can use @Eric5h5’s ObjReader to load models at run time without the need for Pro. It is easier to use Asset Bundles to enable more complex sets of objects to be loaded if you buy Pro.