- Home /
Performance differences in UnityGUI versus GuiText/Texture?
I've seen occasional talk about the performance of various GUI features, and how to improve them. But I haven't found a comparison of the performance between UnityGUI, the all-in-one GUI interface (what OnGUI() does), versus the roll-your-own GUI Text/GUI Texture.
So how do they compare? How much does it cost in speed to use UnityGUI/OnGUI()? Assuming reasonably well-designed code, but with a good number of buttons, textfields, etc.
Personally, I would have thought that Unity would do plenty of optimization on UnityGUI. However, I ran across this, while searching for GUI posts: "OnGUI was not designed to be something that you'd actually ship with a product. It's only there so that you can create UI quickly for debugging purposes, or just for placeholders. For a real, shippable UI, you need to roll your own, probably using GuiTexture and GuiText."
Is he right? What is the intended purpose of UnityGUI? Certainly the main Unity manual pages seem to feature it, with not a word about performance issues. Nor does the Optimization section suggest otherwise.
Answer by Eric5h5 · Mar 18, 2010 at 09:47 PM
The comment about "not designed to actually ship with a product" is bizarre. I would ignore it. That said, OnGUI is typically lower-performance. For one thing, it's recalculated at least twice per frame (immediate mode), whereas GUIElements are just set once (or whenever you change them) and have no cost aside from the usual cost of having objects in the scene (such as draw calls). In particular, using GUILayout in OnGUI has even more of a performance penalty because of having to calculate Rects instead of having them supplied. The Unity iPhone docs do suggest not using OnGUI in-game, but only for menu levels.
The benefit of OnGUI is being able to create complex GUI systems relatively easily, and having a much larger set of built-in GUI tools to work with, such as sliders, scrollbars, text fields, etc. The more complex your GUI gets, the more painful GUIElements are to work with.
Both systems have advantages and drawbacks. I use GUIElements for simple items like typical score readouts, health bars, etc., especially since GUIElements are trivial to make resolution-independent, whereas this is possible but annoying with OnGUI. With more complex (and more typically non-game) GUI systems, I use OnGUI.
@Eric5h5, how bad is the performance hit? Has anyone quantified it? I mean, I've seen posts like http://forum.unity3d.com/viewtopic.php?p=267202#267202 where he says, " ~30 GUI.Box's drops my framerate by 100 fps, and a single GUIArea and GUILayout with about 10 items drops it another 50. " Granted this is probably another bizarre post, but that's why it would be nice to see some real numbers somewhere.
@Cyclops: dropping by 100 fps is meaningful only if we knew what the fps was without the OnGUI function. 2000? Then it's $$anonymous$$or. 200? Then it's a lot. At any rate, I don't think it's really possible to say what the performance hit is, since it depends on what you're doing. So far I haven't run into a case where the speed hit was enough to be problematic or even noticeable, but as I mentioned, I tend to use GUIElements for "game" stuff and OnGUI functions for "non-game" stuff.
@eric5h5 if the OnGUI being called twice is the problem, u can fix it to call only once per frame and also avoid using GUILayouts!! then it would be better than GUIElements, coz u can do complex GUI calc. nearly at the same cost as GUIElements!!
restrict the OnGUI to draw only at the repaint event!!
if(Event.current==EventType.Repaint) { }
embed the whole gui code within this!! it works for me and the draw calls are half compared to what i used to get!!
i just tried that, however i had to enter (Event.current.type==EventType.Repaint) to get it working (c#) got me from 275 to 285 fps,
then i tested a gui-function with a for loop i<1000000 giving me 8.3 and 16.5 fps, pretty much showing that OnGUI is called only half of the time within this capsule.
so i can confirm this from my point of view, Thank you!
Answer by DtBeloBrown · Mar 29, 2010 at 08:03 PM
In the context of iPhone, here is some data:
Just plopped some of my UnityGui code from a web project into the Unity iPhone trial and got some numbers. It is a dialog a bit smaller than the size of the screen, with three medium buttons sitting in the middle. Note the number of draw calls are inflated by 2 because of the "unity trial" texture that they put in the corner.
iPhone Unity internal profiler stats: cpu-player> min: 12.3 max: 22.9 avg: 16.2 cpu-ogles-drv> min: 1.1 max: 4.1 avg: 1.4 cpu-present> min: 1.1 max: 4.4 avg: 1.4 frametime> min: 30.1 max: 37.9 avg: 33.7 draw-call #> min: 10 max: 10 avg: 10 | batched: 0 tris #> min: 202 max: 202 avg: 202 | batched: 0 verts #> min: 304 max: 304 avg: 304 | batched: 0 player-detail> physx: 1.2 animation: 0.0 culling 0.3 skinning: 0.0 batching: 0.0 render: 13.3
fixed-update-count: 1 .. 2 mono-scripts> update: 0.1 fixedUpdate: 0.0 coroutines: 0.3 mono-memory> used heap: 262144 allocated heap: 356352 max number of collections: 0 collection total duration: 0.0
And here is my analysis:
10 draw calls for a window with three buttons is perhaps a bit much if you want to show anything else while on iPhone.
There is a thing called GUIManager on the forums somewhere that is supposedly optimized for iPhone and will draw your whole GUI in one draw call.
@DtBeloBrown, thanks for the numbers. Although I'm probably one of the few people not developing for the iPhone - it didn't occur to me to mention platform in the question.
Your answer
Follow this Question
Related Questions
Reduce Draw call for Multiple GUI Textures with same Texture 1 Answer
Can EditorWindows dynamically display interfaces of other Editor Windows ? 1 Answer
dynamic GUI Texture.. clipping and rotation HUD 1 Answer
script to create gui when detection collision between cube and first controler person ?? 1 Answer
WorldToScreenPoint returns the same value when facing the opposite direction. 0 Answers