optimizing GUI

Hi , Im trying to get the GUI to run … well at least with some degree of speed.

To test Ive cut out all my GUI code, im literally just calling

OnGUI()
{
return;
}

But the profiler is still showing it using 20% of my frame rate. In particular there are 6 calls to GUIUtility.BeginGUI() and 4 calls to GUIUtility.EndGUI().

Im wondering whats going on when the GUI shouldn’t be doing anything. What are these calls doing?

Anyone know ?

Thanks

Edit: I know everyone is going to say DONT use the GUI, but Im trying one last attempt to sort this out before I rewrite everything ive done.

The call to OnGUI() is expensive just by itself, before it even does anything. My guess is - and I’m only guessing here - is that it has to do with capturing all the input events on it’s second pass.

I also think Unity’s GUI gets a bad rep. I don’t mind it at all - just takes a bit to get used to and can get out of hand quickly without proper planning.

Some things I’ve run across that can help performance:

  • Atlas your GUI textures so they can be batched as much as possible
  • Use GameObjects to manage your GUI elements so that they can be conditionally enabled/disabled (instead of conditionally executing code in OnGUI at which point the resources for the call have already been expended)
  • This is an awesome GUI implementation pattern

To make GUI code fast you should consider the following things:

  • Do not try and bundle functionality with OnGUI. For example, if you have character movement code and animation code in a singular script. Do not just throw in a OnGUI function, instead make a seperate script. You can not simply turn off GUI but keep other things running.
  • Do not do put in stub OnGUI functions like you have. It takes time to have to queue up the system for a call to OnGUI. Things need to be cleaned up and prepared and thats part of why i think OnGUI is slow.
  • Do not use GUILayout and set this.useGUILayout = false
    This will take what normally would be 2 calls to OnGUI for repaint (layout, repaint) to just a single repaint call.
  • Never use the ‘Time’ class in OnGUI. Its not good practice. OnGUI is not a Update function and can be called various times from various events. By keeping seperate scripts to handle GUI you’re at a much better position to do any time related things in Update which you should.
  • Do not go overboard on using GUI.DrawTexture. If you can do what you want with a GUIStyle in a GUISkin do it.
  • Cache GUIStyles. – if your manually entering a string for every component your essentially doing a string to GUIstyle lookup every time you call it. While that lookup seems to be quite fast you should still avoid it.
  • Consider how important it is to dynamically place your GUI. Though math is very fast it still is best to try and avoid things like constantly calling Screen.width and Screen.height multiple times in a frame. If its important and you thing there will be a lot of resizing of the screen in your game, you don’t have a choice but most of the time it works fine to precalculate all your rectangles on the first frame.

Thanks for your ideas.

I too like the GUI and am loathe to lose it. So far I have got it down to about 10/20% of my frame rate depending on what esoteric machinations its doing behind the scenes.

Ive got all my GUI stuff into one function.

Have made my menus full screen and have replaced on screen icons with 2 Tri planes and use raycasts to press them, which then opens the main GUI window.