Author Topic: [Solved] Forcing an update of every single anchored widget after root rescale?  (Read 5054 times)

bac9

  • Full Member
  • ***
  • Thank You
  • -Given: 2
  • -Receive: 4
  • Posts: 113
    • View Profile
I'm having a bit of trouble with root rescaling and anchors. In short, when I change the root resolution (both in edit mode and in play mode), positions of anchored widgets are not updated correctly.

Here is a simple setup:

  • Anchor a sprite to a panel (say, a background snapped to edges)
  • Anchor another sprite to that first sprite (say, a window covering half of that background)
  • Anchor another sprite to that second sprite (say, a shadow of that window)

When you change UIRoot resolution, widgets are properly updated, but anchor-based positions are not propagated because their positions are based on other positions that were not updated yet.

The only way I can get my UI in order right now is to manually enable and disable UI root object three times, with every update making anchors one level deeper right. I'd love to know if there is a way to instantly invalidate all anchors AND force their update in hierarchical order so that UI will snap itself together in one update instead of taking unpredictable amount of takes. Ah, and few things:

  • Performance is not a concern, I only ever need that operation to run in the edit mode (when I change screen density or rescale the window) and in the very beginning of a play session (when root gets scaled appropriately for a detected device)
  • Every single anchor in the project is set to OnEnable as I don't need any runtime anchor-based updates - but as far as I remember from NGUI code, that has zero effect on edit mode where anchors are using always-on updates
  • I have tried panel.SetDirty (), panel.RebuildDrawCalls (), broadcasting CreatePanel message and all other stuff I found in the documentation, but nothing provides the desired effect - lower hierarchy elements only get their positions updated after manual game object toggling.

_____________________________

Edit: Ah nope, disregard that, forgot about panel.Refresh () which seems to work great there :)
« Last Edit: November 01, 2014, 10:44:03 AM by bac9 »

bac9

  • Full Member
  • ***
  • Thank You
  • -Given: 2
  • -Receive: 4
  • Posts: 113
    • View Profile
On a slightly related note - what is the reason behind UIPanel methods UpdateDrawCalls, CalculateFinalAlpha, LateUpdate and a segment of UpdateWidgets method being explicitly forbidden to run in the Editor play mode (through directives and !Application.isPlaying checks) while they are allowed to run in the deployed builds? I'm not sure I understand the point of that as it makes panel behavior different between editor and real builds.

ArenMook

  • Administrator
  • Hero Member
  • *****
  • Thank You
  • -Given: 337
  • -Receive: 1171
  • Posts: 22,128
  • Toronto, Canada
    • View Profile
It's the opposite. They are always executed in editor mode. !Application.isPlaying. At run-time they are only executed if something changes -- for example in CalculateFinalAlpha there is a check -- have we already executed this function this frame? If so, skip it. In editor, it's forced to run.

bac9

  • Full Member
  • ***
  • Thank You
  • -Given: 2
  • -Receive: 4
  • Posts: 113
    • View Profile
That's exactly what I'm talking about, they do not run in Editor play mode while they do in edit mode and standalone build. At least that's the impression I get from this pattern:

  1. #if UNITY_EDITOR
  2. if (!Application.isPlaying) UpdateDrawCalls(); // wouldn't that make editor play mode the only excluded situation?
  3. #endif

A simple example is calling Refresh on the root panel after changing screen dimensions. In editor edit mode, it works great, updating all interdependent anchors. In the deployed build it does the same. And only in editor play mode it seems to be cut off by the check and does nothing, making repeated forcing of OnEnable method through toggling root GameObject the only working option to force anchor update. What is the intent behind introducing that difference between builds and editor play mode?
« Last Edit: November 03, 2014, 06:52:06 AM by bac9 »

ArenMook

  • Administrator
  • Hero Member
  • *****
  • Thank You
  • -Given: 337
  • -Receive: 1171
  • Posts: 22,128
  • Toronto, Canada
    • View Profile
Eh? Application.isPlaying is going to be 'true' when running in stand-alone, or after hitting the Play button. It will be 'false' while the app is stopped in the editor.

bac9

  • Full Member
  • ***
  • Thank You
  • -Given: 2
  • -Receive: 4
  • Posts: 113
    • View Profile
Ah damn, you're right. That's what I get for staring at the screen for too long. :)