- Home /
Why is OnGUI called significantly more than Update and FixedUpdate?
Introduction:
I think it’s well known amongst the Unity community that OnGUI has very bad performance when making games, especially for mobile platforms.
In my personal experience it seems to be the highest CPU drain in my current project while running mobile profiling.
(Profiles taken july 17th)
I ran some profiling on my project back in July and found that GUI.repaint was the highest CPU drain on my PC at 3%.
However I’m much more concerned about the OnGUI performance for mobile platforms. And on my Samsung Galaxy Nexus the profiler break down was like this on average:
Camera.Render = 44% GUI.Repaint = 17% (this was biggest one on PC at like 3%) Physics.Simulate = 15% MeshSkinning.Update = 6%
Camera render being so high is sort of to be expected since we are trying to really push the limits and innovate as much as possible for what newer devices are capable of. But GUI.Repaint at 17% the seconds biggest CPU drain? This seems unacceptable to me.
So OnGUI is either the highest CPU Drain or the second highest CPU drain on both PC and my phone last time I checked.
So I’ve been meaning to investigate this a little bit more since the Unity documentation always seems to be completely void of any useful information I’m wondering about. Finally got around to running a few tests today.
The Test:
All tests will be run in my current game project in the exact same location and camera angle where you start the first level. This area has a large smoke particle effect for the crash site, and I also added 15 armor pieces to the camera view which all have particle systems, so this test should be a little more stressful for mobile platforms.
Create 3 int variables to track how many times OnGUI, Update, and FixedUpdate are called by incrementing the individual counters for each of those function calls. Counters will be displayed in OnGUI.
Will be testing in the Unity Editor, PC, and 2 Android devices.
Each test will attempt to accurately measure the number of OnGUI calls in relation to the Update and FixedUpdate calls. Running each test twice for each platform and taking a screenshot when the OnGUI counter reaches 1000. Then converting all the counters to what they would be if OnGUI was exactly 1000 in the screenshot (hard to take screenshot exactly right since OnGUI is called an insane amount of times per second). Averaging results of the 2 tests per platform or device.
Will be running majority of tests with Application.framerate set to 30 to mimic a mobile build. Also doing a round of tests with Application.framerate of 10000 for PC, and Unity Editor. Using default Unity settings for FixedUpdate. Fixed Timestep = 0.02 and Time Scale = 1 (50 FixedUpdate calls per second).
Test Results:
Unity Editor with PC settings:
Test 1
Target Frame Rate = 30
Actual Frame Rate = 30
OnGUI = 1000
Update = 493
FixedUpdate = 816
Result = 61 OnGUI calls per second
Test 2
Target Frame Rate = 10,000
Actual Frame Rate = 304
OnGUI = 1000
Update = 499
FixedUpdate = 82
Result = 610 OnGUI calls per second
PC Build:
Test 1
Target Frame Rate = 30
Actual Frame Rate = 30
OnGUI = 1000
Update = 494
FixedUpdate = 818
Result = 61 OnGUI calls per second
Test 2
Target Frame Rate = 10,000
Actual Frame Rate = 950
OnGUI = 1000
Update = 494
FixedUpdate = 26
Result = 1923 OnGUI calls per second (had to take screenshots @ 10,000 OnGUI and convert values since so fast)
ANDROID TEST (Samsung Galaxy S4)
Test 1
Target Frame Rate = 30
Actual Frame Rate = 29
OnGUI = 1000
Update = 484
FixedUpdate = 842
Result = 59 OnGUI calls per second
ANDROID TEST (Samsung Galaxy Nexus)
Test 1
Target Frame Rate = 30
Actual Frame Rate = 26
OnGUI = 1000
Update = 488
FixedUpdate = 922
Result = 54 OnGUI calls per second
One final test to see what happens when adding the OnGUI counter to all the enemies in one of my scenes… (all previous test are just one script's calls).
Final PC Tests:
Test 1
Target Frame Rate = 30
Actual Frame Rate = 30
OnGUI = 1000
Update = 8
FixedUpdate = 13
Result = 3943 OnGUI calls per second (had to take screenshots @ 100,000 OnGUI and convert values since so fast)
Test 2
Target Frame Rate = 10,000
Actual Frame Rate = 894
OnGUI = 1000
Update = 9
FixedUpdate = .48
Result = 105,144 OnGUI calls per second (had to take screenshots @ 1,000,000 OnGUI and convert values since so fast)**
Test 3 (same as Test 2 except adding OnGUI counter to my biggest OnGUI script in scene)
Target Frame Rate = 10,000
Actual Frame Rate = 902
OnGUI = 1000
Update = 8
FixedUpdate = .46
Result = 107,691 OnGUI calls per second (had to take screenshots @ 1,000,000 OnGUI and convert values since so fast)
Conclusion:
So it seems that OnGUI is called significantly more than either Update or FixedUpdate in all scenarios, even when only incrementing the OnGUI count on 1 single script.
The lowest OnGUI calls per second I was able to achieve was 54 with the Samsung Galaxy Nexus aiming for 30 frames per second. This still was slightly over 2 OnGUI calls for every Update.
When changing the target frame rate from 30 to 10,000 the results become much worst. With only one OnGUI script the PC recorded an astounding 1923 OnGUI calls per second. This was also over twice the amount of Update calls, and over 38 calls per FixedUpdate.
When adding the OnGUI counter to increment on the original script in addition to all the enemies in one of my scenes the results became quite frightening even at 30 FPS. 3949 OnGUI calls even at a measly 30 FPS. That is 125 calls per Update frame, and 77 calls per FixedUpdate.
When removing the FPS limit of 30 and letting the PC really fly OnGUI becomes total beast mode. In my final test while adding the OnGUI increment to one additional very large OnGUI script in my scene it recorded a ridiculous 107,691 OnGUI calls per second. Once again 125 calls per Update but a horrendous 2174 calls per Fixed Update.
Final Thoughts:
It is now clear to me why I’ve seen so many people warning others to never use OnGUI. If it is allowed even slight room to be free things can get extremely ugly.
It is unclear to me why OnGUI is called over 2 times as much as Update even in my best scenario.
It seems strange that OnGUI is called so many times when it seems like it should be called in sync with Update ideally. What is the point of it updating faster than the frame rate? When using it on multiple enemies throughout a scene for things like floating combat text and their health bars it becomes quite ridiculous how many times it is called. I have seen suggestions to disable Game Objects to avoid OnGUI if they are out of range. That makes a whole lot of sense when I’m seeing 125 OnGUI calls per Update even at 30 FPS.
The scary thing is that I didn’t even add the OnGUI counter to many other objects in my scenes that include it! Many of my items like health potions include OnGUI for floating text when you pick it up. So the true OnGUI calls per Update and FixedUpdate are even worse than this report.
After looking at all this data it is no surprise that OnGUI is the biggest CPU hog on PC, and takes up over 17% on the Samsung Galaxy Nexus. That profiler test was taken in July so it’s hard to say how high it is now with many optimizations but also many additions to the project.
Even though OnGUI looks to be horribly inefficient compared to Update and FixedUpdate if used carefully and in moderation it seems that it is useable for even mobile devices.
It seems the people saying it was impossible to use OnGUI effectively probably did not do things to limit the frame rate to 30-60. I would also strongly advise people to use very efficient logic in OnGUI. For example if you are using a for loop in OnGUI you should be extra careful to make sure it only runs when absolutely necessary like once per user action not every OnGUI call. I know this is programming 101 but I’ve seen people struggling with questions while doing stuff like for loops every OnGUI call. Any inefficient code will be greatly multiplied in OnGUI due to it being called so many more times than Update or FixedUpdate!
The majority of the OnGUI logic should be preset you should have variables for all the positions, sizes, etc. Do not calculate these in OnGUI!
OnGUI is definitely an ugly beast of a performance hog, but if used carefully it is very convenient to set up certain displays. Really hoping the new GUI update in future Unity versions will greatly improve the performance though. It’s quite shocking how slow OnGUI is currently.
OnGUI is called at least twice every frame because when using GUILayout you need two phases: layout and repaint. The normal GUI calls might get away with only one.
Did you do any tests with useGUILayout set to false in Start etc.? GUILayout takes most of the CPU processing power because it needs to compute the positions of all dynamically positioned (i.e. everything using GUILayout) GUIelements.
Duplicate question. http://answers.unity3d.com/questions/159938/ongui-updates-several-times-a-frame-why.html
Basically, the GUI goes through various phases: layout, input, render, etc.
Yes, it did appear that some of the more favorable OnGUI call results were about 2 per Update but always a bit more.
It just seems like a really bad system overall for CPU performance even when using frame rate limits like 30 FPS.
I will have to look into useGUILayout, I'm not sure if that applies to my project or not.
Normally I just use GUI.$$anonymous$$atrix, GUI.Label, GUI.DrawTexture, GUI.Button. That really seems to be all I've needed so far but I would love to find ways to increase performance not sure if the disable useGUILayout could help or not at this point.
It just seems very inefficient to me and I've seen many people complain about OnGUI performance so I wanted to do a bit of investigation.
Does anyone know if the new GUI system they announced will improve this? It seems to me that under optimal conditions you should be able to accomplish anything in one Update frame if all it does is display stuff... $$anonymous$$aybe I'm just not getting something here though?
Here's a screenshot of my current project and I use a ton of GUI, just annoying to see it as the biggest CPU drain on PC and second biggest on mobile :(
hey @Ryan - just curious, why are you using GUI? $$anonymous$$any (most?) developers just never use it in products. (I mean it's fine for during development to bring up a dev button or something.)
So what do developers use then for that kind of stuff in Unity projects? When I came to Unity I was still very new to program$$anonymous$$g and OnGUI has been the only thing I've learned that allows me to scale the project to any screen dimensions for mobile devices using the GUI.matrix
At this point I've become very comfortable working with it and I think it looks fine generally. But I'm guessing most developers don't use it because the performance cost? Or is there something better to use? Would love to see some alternatives.
The main reason I did all this research and made this question was because I wanted to see how it specifically effected my project, I just like knowing how things work. But also I wanted to make a point about how slow it is for CPU and since it's such a big part of Unity I was hoping to bring some attention to this issue for future improvements.
Answer by Fattie · Oct 09, 2013 at 08:43 AM
"So what do developers use then for that kind of stuff in Unity projects?"
Hey Ryan, for "sprites" in Unity, many teams use 2DToolkit. Just get it from the asset store. (It's a shame to recommend some particular asset so often but, in practice, you can't use Unity without it, or a competitor product.)
It's basically impossible in practice to do a unity project without some "sprite" solution. So just get 2dToolkit or one of its competitors.
(Note that, indeed, next yr Unity is including their own "unity 2d" to handle sprites easily - presumably this will very much annoy the 2DToolkit guys and the other package makers like that!!)
By the way by "sprites" I simply mean when you have a flat plane (at worst you could just choose "make plane") with an image (ie, a texture) on it.
You could say, it's a 2.5D element -- meaning you're using a 3D thing (it's really a flat plane, that just happens to be oriented towards a camera) as a 2D thing.
Note that sprites have a broad range of uses. of course, if you're literally making a "2D" game (imagine mario, a sideways scroller arcade game) - then it's not really 2D, it's literally a 3D world but it just happens to look like 2D. So when you look over the shoulder of a developer making a 2D game, it's actually - in full 3D - all these flat "sprites" in 3D, it just happens to look like 2D from the camera point of view.
(I have no idea what you do or don't know, so I'm explaining all this.)
Again note that even in totally 3D games (eg, grand thefy auto etc) you will inevitably need 2d "sprites" for some reason or another (eg, for alerts, things floating in space, whatever).
So the first thing is, no matter what you will have 2DToolkit (or similar) in your project.
Now - the horrific question of how to show type on the screen. The one and only easy way to do this in practice that solves all problems:
http://answers.unity3d.com/questions/384623/setting-font-size-according-to-screen-dpi.html
explained at length in my comment there (with the two pictures)
For the simplest possible type needs (say during development, you need to bring up a value on the screen) to the most tricky "UI" uses of typography ... that pipeline is by far the simplest and only way to do it.
To change the text seen, the code is just like "thing.text = "3.71"; thing.commit();" and that's it.
to put one in the scene you just click "add new text mesh" and you type in what you want it to say. You can have any typeface you want (see explanation in the link above).
So we have established:
(a) you have to have "sprites" (flat images) in all games. no matter what, you'll have to have a sprite solutin on hand.
(b) inevitably you will use 2dtoolkit (or some competitor) to do this. (I suppose you could spend a year programming your own convenience routines to make using sprites easy.)
(c) for the critical question of typography in unity, the pipeline i show in the link above is the only working answer we have ever found
(d) and critically .. everything in unity should be "2.5D", anything that breaks that paradigm is crap.
Now you want to know about doing "UI" which is a sort of conceptual NON 3D layer "touching the viewer"
So the answer is trivial - you use your 2.5D workflow (ie very likely literally 2dtoolkit) and you simply make that a layer near the camera! (Or use a second camera if you prefer, just sit it to one side.)
Conveniently, the 2dtoolkit guys include a complete "Buttons" script and a complete "UI" script which gives you all functionality of these paradigms. (They are only short scripts - rather making a mockery of the whole "gui industry" if you ask me - I personally don't use 'em coz we have our own buttons system (ie, oe or two short scripts) and I always feel UI is beneath a Real games programmer, who should spend his or her time making explosions, so I just roll my own "ui" as the need arises!)
The absolutely critical philosophical point:
If you make your UI using sprites then you are still in the 3D paradigm (ie, it's "2.5D" if you wil -- "2.5D" means you are actually using 3D elements but it just happens to look flat to the end-user.)
Whereas unity's GUI system is a pretend 2D system, so it will never give any happiness in this universe. (Eric kindly explained to me the other day, if I did not misunderstand him, that the actual Unity editor is made using unity's GUI system - so, that's exactly the perfect job for it.)
Now as well as Unity's GUI you have "better than unity GUI" products notably NGUI and EZGUI. These are absolutely admirable products and I'm sure I'll meet the makers one day, and they are technically superb and very popular - you should definitely pay money for both to check them out. But for me they are utter non-starters because ("no, really") they are big complicated APIs you have to learn and for me that's (a) not possible as I'm not able to learn anything and (b) it's just beyond human belief anyone would want to learn, become a specialist, in a system to make UI. (Because, you simply do it in "2.5D" with sprites .. ie, ... utterly exactly as you do anything else in Unity.) Thus, let's say you are really good at making things move around in Unity - I mean tanks, soldiers, and the like. Thus, automatically, with no further effort, you are really good at making things (that happen to be flat sprites) move around in Unity; so indeed you can instantly program any and all UI (ie "things which happen to be flat things, which move around, just like the more normal tanks etc")
I hope these thoughts are of interest! Cheers!
PS if you're fussing about nonsense like drawcalls, I believe systems like 2dtoolkit give you 1 drawcall for all so that's the end of it. Also just as you say "what's up with the loop" - if you use a normal 3D system it's just exactly the same as anything else in your game (tanks etc) so there is no further thought or investigation.
Thank you! All this information is extremely useful to me and I'll be sure to check out all the stuff you mentioned!
I agree having to focus so much on the UI is a bit of a pain I'd rather be doing cool stuff like trying to improve my enemy AI for example. Unfortunately I'm the only programmer on the project and just working with 1 artist so it's so much to learn sometimes I don't know what to focus on or where to begin. So all the detailed answers and recommendations for alternative solutions is very helpful to myself and I'm sure a lot of other Unity users!
The Real trick to development work like this is.. work on paper with a pencil. The process becomes clearer and your priorities become laid out. You can clear you $$anonymous$$d and focus on your next task.
I'm not sure what $$anonymous$$eat is referring to, but he is totally correct.
One of the cleverest things anyone has ever said: Einstein said: "$$anonymous$$e with a pencil, is smarter than just me." It's an unbelievably clever observation that goes to the nature of processing, consciousness, program$$anonymous$$g, and reality.
I am always telling people to draw, draw, draw, first step us pick up your rigging pencil.
http://answers.unity3d.com/questions/266972/detecting-mesh-orientation.html
http://answers.unity3d.com/questions/293607/tiling-uv-mapping.html
http://answers.unity3d.com/questions/435703/procedural-uniform-uvs-on-a-plane.html
Secondly, there's only one pencil you should use as your rigging pencil. The cult pencil is the $$anonymous$$bow $$anonymous$$ono100. It will change your life. (Obviously you need a kum as2 sharpener it goes without saying.) Regarding your croquis there are many good ones but I recommend Canson 90 gmm.
Great point by @$$anonymous$$eat
Answer by Bunny83 · Oct 09, 2013 at 01:45 AM
Maybe my GUI crashcourse will shed some light into your confusion?
The main problem with the GUI system, on mobile devices, is that each GUI element might have 0 to 3 independent drawcalls (3 only if you use a style with background image and a GUIContent with text and image). A normal Label has one draw call a usual Button has 2 (text and background image).
You shouldn't judge OnGUI on the times it's called. In the layout event the controls just doing some calculations. All controls from the GUI class completely ignore the layout event, so when they are called they just early-exit right at the top.
On mobile devices drawcalls are the real problem. Each drawcall is a seperate "command" sent to the GPU. That mainly drains CPU power. That's why it's better to havethings with more vertices / triangles and just one drawcall for the whole thing instead of hundreds of single drawcalls.
NGUI is a framework which builds a mesh out of all "widgets" in a panel and only needs one drawcall. Btw: afaik the person that made NGUI is curently working on the new GUI system of Unity, so hopefully we get some sort of hybrid system which is as flexible as OnGUI and as performant as NGUI.
ps: Can you tell us how many GUI elements you actually draw on screen? I've created a quite complex debugging system for mobile using the Unity GUI system and it doesn't preform that bad. You can also check the drawcalls in the "stats window" in Unity, try disabling the script with GUI stuff at runtime and see how much the drawcalls change.
Thanks for all the info! I'll read through the GUI crash course in a bit here.
I wouldn't judge it based purely on the # of calls, but I think that is a pretty good illustration of some of the problems of it not being very well optimized. If I am only seeing about 10% of the OnGUI calls at any given time it's kinda bad if the other ones I can't see and are therefor useless might be firing around 2000 times a second without a frame rate cap.
Even if they early exit right at the top I imagine with so many useless calls that does add up for mobile devices.
I'll have to get back to you on the draw calls after I have time to test out disabling some of them.
It seems you are really confused how OnGUI works. OnGUI is THE event callback in Unity. The early exit is true for the layout event which happens exactly once each frame. The repaint event (which also happens exactly once per frame) is responsible for actually drawing the element. Since the GUI system is an immediate system, that means the moment you call for example GUI.Button inside the repaint callback it immediately draws the background and the text into the framebuffer. That means what is actually displayed is created by what's inside the OnGUI callback.
Such a system only works when the repaint event is called every frame. It's impossible to skip any call of OnGUI.
Beside layout and repaint there are other events for which OnGUI is called but they depend on actual user generated events (mouse / touch / keyboard input). Again "a call" of OnGUI can't be accumulated since each call has a completely different purpose. The problem certainly isn't how often it is called, only the number of drawcalls.
Yes, it might have been possible to implement some automatic culling on the CPU and don't draw an element if it's outside the screen, but it would remove the flexibility of this system. Inside the repaint event of OnGUI you could even use the GL class to directly draw any kind of stuff (2d / 3d lines, triangles, quads, meshes, cameras, ...)
Interesting information thanks!
So are you saying that the call counts themselves have absolutely no effect on the CPU? It seems that when I'm getting over 100,000 OnGUI calls per second in some of my tests that would have an effect even if they don't add to the draw count?
I will try to do a test on the draw calls in the next few days with disabling OnGUI, as well as do another profile test since it's been several months since the last.
I'm not sure if you can completely discount the # of OnGUI() calls for mobile performance, or even PC for that matter since it was the highest use but only 3%.
If you only used OnGUI() for like buttons and menus and have it all contained in one script that would a lot more sense to me that the OnGUI calls isn't really important compared to draw calls.
But in my case I find it very easy to set up health bars for enemies and floating combat text for enemies or items using OnGUI in all their scripts. The problem is that these OnGUI() calls are occuring 1000's of times a second collectively in any given scene. $$anonymous$$uch worst is that the majority of them aren't even displaying anything. Each enemy has to pass a series of bool condition checks to deter$$anonymous$$e if their OnGUI should proceed otherwise you could just see like 50 health bars wherever you are on the map.
I realize I could combine these multiple OnGUI condition checks in Update() before release with a really big Update condition check resulting in just one bool for the OnGUI. But that's still not just an empty call they are checking conditions every time :(
So currently I am checking probably 10,000+ conditions (guesstimation) every second due to OnGUI being called so many times even at 30 FPS. I could reduce this to around 2000-3000 per second by using one bool in each GUI ins$$anonymous$$d of multiple I have now and I'll be sure to do so before release. But still that seems like WAY too many for mobile especially when like I said 90% of them probably aren't even showing up on screen until you kill almost all the enemies.
That's what I mean by you need to disable entire Game Objects to avoid the excess GUI calls.
I think there should be a way for them to do this without reducing the flexibility of the system. Like why isn't there a simple game engine variable for all gameobjects similar to renderer.enabled = true.
Couldn't they fairly easily add the same kind of thing like OnGUI.enabled = true in a future version of Unity? So you could easily toggle whether OnGUI is called for any given Game Object? This could in some cases prevent 100,000+ wasteful OnGUI calls per second according to my tests. Would be very nice in my opinion.
Your last request tells me that you still have trouble with the concept of Unity and behaviours in general. Unity can't automatically deter$$anonymous$$e if it should or shouldn't call the OnGUI callback. If you have written one, it will be called, period. Since it's completely up to you what you do in OnGUI that's the only option Unity has.
Next thing is: if you don't want your script to be executed, disable it! It's as simple as that. You can even use OnBecameInvisible and OnBecameVisible to enable / disable a script based on if it's visible on screen or not. $$anonymous$$eep in $$anonymous$$d that the point of a component system and behaviour scripts is to be more flexible. You should keep the scripts short. Each component should have one purpose.
Complaining that OnGUI is called for every event is like complaining that Update is called every frame. The purpose of OnGUI is to let you handle any of those events.
If you use OnGUI it is up to you how you use it. For example i've made a complex GUI system with only one $$anonymous$$onoBehaviour that has an OnGUI function. I've distributed the call to other objecty myself, in the order i want and in the state i want.
If you have a lot OnGUI calls which are useless it's your fault, not the fault of Unity.
Answer by kookyoo · Oct 08, 2013 at 01:33 PM
Hi,
Don't know for the latest version, but before the new GUI there were some issues due to the multiple calls to OnGUI. There were a call for the creation of elements, another for the layout and finaly a repaint one used to draw the final result. I don't exactly remember the exact flow but it's something like that, it was leading me to issues so I had to check wich event called the OnGUI to change what kind of code must be executed.
Yeah it's a huge pain to deal with it. When I first discovered OnGUI was draining the CPU so much I was kinda shocked. It seems like it should be so simple and light on the processing power to me :(
I really think the number of calls are just way too excessive. Really hoping they are doing something to improve this soon.
Also they are called non-stop even if you can't see 90% of the stuff they are doing in the scene?! I think the only solution is to just disable the entire Game Object to avoid this? Seems a bit extreme to me.
Like why don't they have some kind of variable to set the max speed of OnGUI? I would love to be able to set it to 30 calls per second like Update. I think it'd be worth it for them to add something like that especially for older mobile devices.
OnGUI is immediate mode; any frame that it's not called is a frame that it won't be visible. Typically there are two loops in OnGUI every frame, once for layout and once for repaint. It's necessary and not excessive at all, given that OnGUI is immediate mode as I mentioned. I don't really know what you're talking about with disabling game objects.
It seems that OnGUI is called twice every frame regardless. I'm not sure what you mean any frame it's not called? It appears to be called no matter what even if the OnGUI is not visible on the screen.
For example if I have 25 enemies in my scene, and their OnGUI is responsible for displaying their health bars and floating damage if I hit them. Even if I am further than 50 meters away from the enemy so their OnGUI will return immedietely, their OnGUI() is still called an insane amount of times as shown in my tests.
Example:
void OnGUI()
{
if (GUIButtonsScript.gamePausedBool == true)
{
return;
}
if (DataChipScript.data$$anonymous$$enuBool == true)
{
return;
}
if ((inRangeofPlayerBigTrigger == true) && (playerLineOfSightBool == true) && (enemyRenderer.isVisible)
)
{
//if it passes all these conditions it finally does things visually
}
}
Sorry for formatting copied directly from project not working quite right here.
But with that example even if you only perform GUI logic in specific conditions for an enemy or any Game Object it still will call the OnGUI() over twice for every Update.
Even if the enemy is like 500 meters away and they have nothing to do with OnGUI() they are still called right?
So by disabling the Game Objects entirely you can avoid the insane amounts of OnGUI() calls in a scene.
It would be much more convenient if there was a way to disable OnGUI calls without disabling the entire object. Or to limit it to a set rate.
What I mean is, if OnGUI didn't run during a particular frame, it wouldn't be visible. So it can't be limited to 30fps or anything, it must be called every frame. The only way to avoid that would be to not have it be immediate mode, which would change the entire thing and it wouldn't be OnGUI anymore, it would be a different system.
(I'm personally not really in favor of using immediate mode for a GUI system in the first place, but trying to limit it to 30fps or whatever is basically the worst of both worlds. If it's going to be immediate mode it must run every frame. If it's not going to be immediate mode, then you don't have to worry about arbitrary framerate limitations anyway, it would run only when needed.)
As far as GameObjects go, there's no reason to disable GameObjects just to turn off their OnGUI code...simply disable the OnGUI script ins$$anonymous$$d. Another approach is to have one script controlling the GUI for all objects, which is recommended if you have a lot of them, since looping through the objects yourself in one script avoids the overhead of having an OnGUI function call on many objects.
How do you disable the OnGUI Script? Is there actually a function similar to renderer.enabled = true except for OnGUI?
Currently the only way I know how to disable OnGUI is by:
void OnGUI()
{
if (condition)
return;
}
If there is a way to do it without even having to read conditions inside OnGUI that would be amazing! I think it's just called too many times to even read conditions within OnGUI for mobile platforms.
Edit: I think I see what you're saying now. So you mean I should make OnGUI() be separate from the rest of the enemies script? So ins$$anonymous$$d of having everything in one script for an enemy I could use 2 and one would only contain OnGUI()?
That seems like it would work but I'm not sure how much more convenient it would be than just disabling the game objects in my particular situation. Even my smallest enemy scripts are around 500 lines long although I tend to code with a lot of extra space for readability and to separate logic. I would also have to change a lot of my variables to be publicly accessible and the OnGUI() script would have to retrieve lots of information from the other enemy script for it's position relative to the camera, player, line of sight, isVisible, behavioral bools, health value, etc.
So it would be a lot of extra work but maybe it would be worthwhile before release, seems all that communication between scripts and more public variables might counteract any benefits from not calling OnGUI() but I don't know enough about program$$anonymous$$g performance so I'm just guessing there.
Still seems like a lot of extra work for something that in my opinion should already be a feature in Unity to just disable a Game Objects OnGUI() with a simple one liner like:
OnGUI.enabled = false;
If there is another way to disable OnGUI please let me know how to use it haha, I am a super program$$anonymous$$g noob in the grand scheme of things.
Answer by meat5000 · Oct 10, 2013 at 08:03 AM
It's "one call per event"
as said in the scripting reference. Reduce events, reduce calls.
(I like GUITextures. They are fast and responsive.)