Author Topic: 123ms UIPanel.LateUpdate!?  (Read 29786 times)

Drexster

  • Guest
123ms UIPanel.LateUpdate!?
« on: July 31, 2012, 06:39:02 PM »
Was just profiling my game on iOS 4 trying to do some serious optimizations and I noticed after playing for awhile the frame rate was dropping considerably.

In the unity profiler UIPanel.LateUpdate peeks at 123.43ms at one instance! And seems to spike every 30 or so frames.

I have 3 panels in my scene, 1 for GUI, 1 to render particles and fx to and 1 for tiled animated sprite as a background.

I noticed my GUI panel starts off with 20 widgets in it, and as soon as an animation plays that number goes up to 45. During gameplay my HUD only consists of 15 visible widgets, but the panel still claims 45.

The panel i'm using to render FX never really goes over 10-15 widgets, but could theoretically go as high as 40-50.

When profiling It doesn't seem to be either the FX or Backgroun panels which are costing, but the GUI panel.

I saw a post regarding "offscreen UIPanel Lateupdate" and "disable when finished" option of UIButtonPLayAnimation... i have a few UI animations playing independently from NGUI's messaging (due to an incompatibility with Unity's animation event system) and am wondering if there's a cost with not calling "disable when finished"? I mean the widgets are disabled at the object level when not being used, that should be enough, right?

Is there something else that could explain the crazy high ms cost?

-EDIT-
Also, if not using UIAnchor on any active widgets, is there any reason why it would need to be called every frame? and costing upwards of 50ms on some spikes? The only ones in my scene are located on the parent object above the panel.
« Last Edit: July 31, 2012, 07:31:39 PM by Drexster »

ArenMook

  • Administrator
  • Hero Member
  • *****
  • Thank You
  • -Given: 337
  • -Receive: 1171
  • Posts: 22,128
  • Toronto, Canada
    • View Profile
Re: 123ms UIPanel.LateUpdate!?
« Reply #1 on: July 31, 2012, 10:33:12 PM »
That's way excessive. You need to move your animated widgets into their own panel, if possible. Them changing every frame means that the draw buffer used for them must be re-created every frame -- and if they have 44 other widgets under the same panel that means 44 others also get affected.

Additionally, if possible, animate panels, not widgets themselves. Animating panels has no performance cost at all. So for example if you have a window moving into view, make sure that that window is actually a panel.

Disable When Finished state means that the game object will be disabled after the animation or tween finishes playing. When it's disabled it costs no resources, so it's generally a good idea to do that. Note that this is only advisable if you animate something and move it off-screen where it can be disabled without it being obvious to the user.

Drexster

  • Guest
Re: 123ms UIPanel.LateUpdate!?
« Reply #2 on: August 01, 2012, 12:45:53 AM »
Thanks for the reply Aren.

I'll try to rebuild the UI using more panels. Is there any associated cost to this? or could I theoretically do every screen as a separate panel?

Regarding the disable when finished, is this any different then disabling the object using SetActiveRecursively()? Currently for some of my screens after animating out of sight i disable them, just not using the NGUI "disable when finished".

ArenMook

  • Administrator
  • Hero Member
  • *****
  • Thank You
  • -Given: 337
  • -Receive: 1171
  • Posts: 22,128
  • Toronto, Canada
    • View Profile
Re: 123ms UIPanel.LateUpdate!?
« Reply #3 on: August 01, 2012, 12:58:38 AM »
The cost of more draw calls. Each panel adds a new draw call, but it's better than the alternative, especially for moving things around.

I suggest using NGUITools.SetActive instead, as it's consistent. SetActiveRecursively doesn't enable objects in the proper order. It enables children before parents, which is bizarre.

simon129

  • Newbie
  • *
  • Thank You
  • -Given: 0
  • -Receive: 1
  • Posts: 20
    • View Profile
Re: 123ms UIPanel.LateUpdate!?
« Reply #4 on: August 01, 2012, 01:13:38 AM »
That's way excessive. You need to move your animated widgets into their own panel, if possible. Them changing every frame means that the draw buffer used for them must be re-created every frame -- and if they have 44 other widgets under the same panel that means 44 others also get affected.

Are tween color and tween scale also "animated widgets" and cause UIPanel to rebuild the buffer, or just position related tween ?

thanks

ArenMook

  • Administrator
  • Hero Member
  • *****
  • Thank You
  • -Given: 337
  • -Receive: 1171
  • Posts: 22,128
  • Toronto, Canada
    • View Profile
Re: 123ms UIPanel.LateUpdate!?
« Reply #5 on: August 01, 2012, 01:14:57 AM »
Tweens aren't widgets. When tweens are placed on widgets, they indeed cause rebuilding. Changing anything other than moving, scaling or rotating the panel is changing the buffer.

simon129

  • Newbie
  • *
  • Thank You
  • -Given: 0
  • -Receive: 1
  • Posts: 20
    • View Profile
Re: 123ms UIPanel.LateUpdate!?
« Reply #6 on: August 01, 2012, 01:22:34 AM »
If I have a large UIPanel and have about 50 widgets on it, only 1 of them with a looped color tween and others are static buttons, should I isolate that widget to it's own UIPanel to avoid the whole UIPanel to rebuild the buffer on every update to gain better performance ?

Thanks

ArenMook

  • Administrator
  • Hero Member
  • *****
  • Thank You
  • -Given: 337
  • -Receive: 1171
  • Posts: 22,128
  • Toronto, Canada
    • View Profile
Re: 123ms UIPanel.LateUpdate!?
« Reply #7 on: August 01, 2012, 01:23:20 AM »
Absolutely.

nah0y

  • Sr. Member
  • ****
  • Thank You
  • -Given: 1
  • -Receive: 2
  • Posts: 430
  • \o/
    • View Profile
Re: 123ms UIPanel.LateUpdate!?
« Reply #8 on: August 01, 2012, 05:30:53 AM »
Thanks for the performance tip !
You should put that in BIG RED on the website tutorial :)

PS : That means that if I want to move a group of GameObject, I should put my TweenPosition script onto the same GameObject that has the UIPanel, right ?

Is it also true for items in a draggable panel ? Each 'row' should be in its own panel ?
« Last Edit: August 01, 2012, 05:33:17 AM by nah0y »

ArenMook

  • Administrator
  • Hero Member
  • *****
  • Thank You
  • -Given: 337
  • -Receive: 1171
  • Posts: 22,128
  • Toronto, Canada
    • View Profile
Re: 123ms UIPanel.LateUpdate!?
« Reply #9 on: August 01, 2012, 06:16:15 AM »
Yup that's right -- tween the panel.

No, draggable panel is still just one panel (assuming you're talking about UIDraggablePanel script). The way draggable panel works is it adjust its position and that of its clipping instead of actually moving the widgets, resulting in high performance.

nah0y

  • Sr. Member
  • ****
  • Thank You
  • -Given: 1
  • -Receive: 2
  • Posts: 430
  • \o/
    • View Profile
Re: 123ms UIPanel.LateUpdate!?
« Reply #10 on: August 01, 2012, 06:17:11 AM »
Perfect, thanks.

Yes I was talking about UIDraggablePanel.

nah0y

  • Sr. Member
  • ****
  • Thank You
  • -Given: 1
  • -Receive: 2
  • Posts: 430
  • \o/
    • View Profile
Re: 123ms UIPanel.LateUpdate!?
« Reply #11 on: August 01, 2012, 09:05:16 AM »
PS : Same thing for a SpriteAnimation ? Does the fact that the sprite is changing every frame has an inpact on the other elements of the panel ?

ArenMook

  • Administrator
  • Hero Member
  • *****
  • Thank You
  • -Given: 337
  • -Receive: 1171
  • Posts: 22,128
  • Toronto, Canada
    • View Profile
Re: 123ms UIPanel.LateUpdate!?
« Reply #12 on: August 01, 2012, 10:39:32 AM »
Yup.

Drexster

  • Guest
Re: 123ms UIPanel.LateUpdate!?
« Reply #13 on: August 01, 2012, 01:17:33 PM »
I've redone my GUI with more panels. Was easier then i thought, I just added a UIPanel component to each major UI object's parent, which kept most animations intact and i then removed the 1 major UIPanel object. I havn't profiled on iOS yet, but will shortly.


I also just realized I have an object i'm using NGUI to render various animated sprites on, and subsequently animation the geometry. I was using my FX panel for this, but now I'm wondering if i'd be better off giving each object it's own panel? Or even just ditching the panels and using an animated UV texture...? The original idea was that i'd be batching the draw calls together down to two for all these objects. I guess i'll have to do some more tests.

Drexster

  • Guest
Re: 123ms UIPanel.LateUpdate!?
« Reply #14 on: August 01, 2012, 01:31:43 PM »
With 9 of these objects on screen and nothing else in the scene, the PC profiler shows UIPanel.LateUpdate as taking 0.17/0.48 each first and second frame when rendered through a single panel.

When each object is given it's own panel the profiler shows 0.23/0.68 each first and second frame. So i guess it's safe to assume in this particular case using 1 individual panel would be ok.
Maybe what I will do is create multiple panels based on the FX type.


Also note using a single panel makes the difference between 3 and 19 draw calls vs giving individual objects a panel.
« Last Edit: August 01, 2012, 02:16:32 PM by Drexster »