- Home /
How to create a CPU-friendly dynamic interface?
Hello,
I'm struggling with a dynamic interface that changes about every second. Right now I've hung the script onto a camera and do an update every OnGUI(). I have no idea how many times a second the OnGUI updates, but I guess it's the same as update. With the script on the FPS count is max 400. with it off, it gets to 650.
I'm using a lot of GUI.Box'es and GUI.Label's and dynamically reposition them. This can lead up to about fourty changes per frame. I'd like the interface to only update twice a second and be less CPU-consuming. Any ideas on how to do that?
One thing I have considered are using 2D images on the screen instead of real GUI elements (with GUIStyles which, I THINK, are very CPU unfriendly), but I have no clue about where to start putting 2D resizeable images on the screen.
Answer by jashan · Dec 18, 2009 at 12:02 PM
OnGUI is called a few more times than Update as it is called for different events, see also the scripting reference: MonoBehaviour.OnGUI
So, what I'd recommend is keeping the "state" (positions etc.) in your object as member variables (you probably already do it that way) and then do any "animation state changes" in Update(). That's where one would expect these kinds of change anyways, and that's how you'd do it if the GUI changes every frame (which is probably the general case).
Now, in your specific case where you only want "updates" every second or twice a second, instead of using Update() you should probably use a Coroutine with a loop and using WaitForSeconds. In C#, that could look something like this:
public float loopDelay = 0.5F; // half-second delay => twice a second
public void Start() { StartCoroutine(GUIAnimationLoop()); }
public IEnumerator GUIAnimationLoop() { while (true) { // do your GUI change calculations yield return new WaitForSeconds(loopDelay); } }
public void OnGUI() { // do your GUI rendering without any "dynamics", rely on changes from GUIAnimationLoop }
this way, is it possible to also delete and add boxes on runtime?
could you extend your answer for this case (javascript): I'll create an array with all elements, states and positions in Update and want to show it with a for-loop in OnGUI? is this good practice? and even more important: will this cut down my CPU-consu$$anonymous$$g?
You'd "delete and add" boxes by simply having those boxes rendered depending on some flag that you set from the Update()-method or the coroutine. Regarding the array with all elements: sounds like a very reasonable approach to me. As I don't know exactly what you are doing, I can't comment much on what takes so much of your CPU-time or whether such a new approach will really help; but I'd say it's quite likely that it will ;-)
Answer by Ashkan_gc · Dec 18, 2009 at 07:04 PM
generally you should not do calculations inside OnGUI. you can call GUI elements GUI.xxx in Update or any other function but i think calculations are the reason of your slow script. so as jashin said: in OnGUI just call GUI methods and do all other calculations in Update or any other function that you need. if you call GUI methods in Update you might have some problems with receiving events because it will not capture mouse and keyboard events between frames witch is not a good thing for GUI.
Your answer
Follow this Question
Related Questions
Optimizing OnGUI 1 Answer
Deleting GUI Layer creates GC Allocation? 1 Answer
Same Code, Different Variables (Optimization) 1 Answer
Static variables & performance 2 Answers