Tasharen Entertainment Forum
Support => NGUI 3 Support => Topic started by: ivomarel on October 03, 2013, 02:16:15 AM
-
Hey all,
I'm in a pretty far state of my game, built with Toolkit2D and NGUI (and about 10 other plugins, but I think irrelevant). I noticed my game is slow on many of the lower end mobile devices and when I checked with the profiler, I was surprised to see it was the NGUI LateUpdate method which was causing most of the lag. Upgrading to NGUI 3.0 did not help, in fact, it seems even slower.
Anything that comes to mind right away about what I might have done wrong? Or could there be a million reasons? I can get into more detail but I hope there's an obvious answer ;)
I added a screenshot of the profiler, it seems BetterList`1.Add() is making a lot of calls (17532).
Cheers guys
-
Deep profile does not give accurate results. Think of it like this... you have FunctionA that takes 100 ms to execute but only gets called once, and then you have FunctionB that takes 0.001 ms to execute, but it gets called 1000 times.
Math gives us:
100 * 1 = 100 ms to execute FunctionA once
0.001 * 1000 = 1 ms to execute FunctionB 1000 times.
Deep Profile adds X time to each function call. For the sake of this example, let's say it's 10 ms. Now suddenly the math becomes:
(100 + 10) * 1 = 110 ms to execute FunctionA
(0.001 + 10) * 1000 = 10,001 ms to execute FunctionB.
See the problem yet?
-
Hey ArenMook,
Thanks for the quick response. I see your point. Unfortunately, as usual, this raises more questions.
So you're saying this number of calls from this method should not influence performance (too much)?
Would there be a better way to test this?
-
I suggest having a look at what's causing the geometry to be rebuilt frequently, as that's what's ultimately leading to all those BetterList.Add calls. Frequently changing geometry should be moved to its own panel so that it doesn't affect other widgets.
-
Hello Ivo,
We've gained huge increases in performance by properly using the static flag on UIPanels - this will cause the geometry to stop rebuilding.
We're currently using a tween system for our UIPanels that can toggle the UIPanel to static once it stops tweening.
Of course we only apply this if the UIPanel doesn't have any geometry inside that changes normally.
Also be sure to disable panels once you've tweened them out of screen / they are no longer visibile. This will disable any geometry update and rendering.
-
Thanks nameles01 and ArenMook!
I am pretty sure it's because I have about 300 buildings in my screen, all with their own UILabel, but all UILabels are placed in the same panel.
The UILabel is only visible when the building is selected (and moves only when the building is moved) and I guess they should all be in separate UIPanels.
I'll give this a try and let you know if it worked.
-
I ran a test previously with 2.6.3 and the amount of UIPanels seemed irrelevant. Could've changed of course. Interested in your results.
Edit: I've found that in 3.0.1 the amount of UIPanels used makes a massive difference in performance (fewer=better), when exporting to Flash at least.
Edit2: My results for Flash will conflict yours on mobile - that platform is draw call limited and will always profit from using fewer panels since 1 panel == at least 1 new draw call. Therefore the irrelevancy I noticed in 2.6.3 most likely isn't there for you.
-
Hey nameles01, ArenMook, others ;)
Thanks for the extra information - a solution that I found was rather simple. Instead of giving each building it's own label, I move the label around based on which building is selected. Simple enough.
However, I also have some labels that are not only visible when the building is selected. They are visible until the building is tapped ("Tap me")-label. There are about 50 of these and like you said, adding multiple UI-panels will dramatically increase drawcalls. Also, just moving around the map will force the geometry to be rebuilt.
Can someone explain to me this rebuilding of geometry? Toolkit2D doesn't seem to have any issue with moving objects (I'd use Toolkit2D for my labels but I need to use a dynamic font). Is there any way around rebuilding geometry every time the labels move? Or can I use something else than a UIPanel - since they all z-sort together and it's all from the same atlas? Or is the dynamic font actually the cause of my problems?
So many questions, would love to get some answers!
Thanks guys
-
The widgets don't draw themselves. The panels are responsible for drawing widgets in an efficient, batched fashion. If widgets move, the geometry the panels created becomes invalid and has to be re-created. This is done by re-filling all the affected widgets, which is not a fast thing to do.
Moving panels is quick and efficient because nothing needs to be rebuilt.
-
So why does every panel need to be one drawcall? Or doesn't it?
-
Each panel can be 0 or more draw calls. 0 if it has no widgets, 1 if all widgets use the same atlas, 2+ if not. Panels create draw calls as necessary in order to draw the geometry in the correct fashion (in 3.0).
-
So for my problem:
I have 50 widgets in my screen (all from the same atlas)
I want to remove one widget without rebuilding all geometry
There is no options besides having multiple panels which leads to 50 drawcalls, even though the widgets are all from the same atlas with the same z-depth?
-
That's right. Best thing to do is to disable components you don't have visible. Are all 50 widgets visible and moving at the same time? If not, disable those that aren't.
-
Hey ArenMook,
Yes they are all 50 visible at the same time. Does it matter if they are moving? It's only the camera that's moving (zooming/translating - it's an RTS).
If there's no other solution, I might use images instead of text and do this in Toolkit2D.
-
If they aren't moving, turn the 'static' flag on on your UIPanel that draws them.
-
Hey ArenMook,
This does not seem to decrease my drawcalls. Since I'm developing for mobile, 50 extra drawcalls is very expensive. Or am I missing something?
Cheers,
Ivo
-
One panel set to static, 50 widgets inside it.
-
So I remove on widget and that requires all the geometry of 50 widgets to be rebuilt, correct?
Edit: Remove/move
-
Less posting more trying.
-
Hey ArenMook,
Fair enough - I guess your great support made me lazy.
So concluding, the edit in my post was actually essential.
Removing a widget is fine, it works fine, even in a static panel.
Moving is a different story as widgets can not scale, rotate or translate while in a static panel.
I can work with this. I'll give every building a widget all in one static UIPanel, which I'll disable on tap, while enabling a separate widget (for only that building) which tweens.
Thanks again ArenMook for the great support!