Author Topic: Dynamically adding a prefab under a UICamera resets all layers to default  (Read 4187 times)

sourcerer

  • Newbie
  • *
  • Thank You
  • -Given: 0
  • -Receive: 0
  • Posts: 1
    • View Profile
I've been Tracking down a strange input bug

I have two UICameras (main and overlay)

when dynamically adding a prefab (which contains a UIPanel and other fixins) to the one of the cameras (main in my test case) all layers beneath the the UIRoot get updated to whatever layer that new prefab has.

After looking through the code I found that in UIPanel::UpdateLayers() there is an IF statement that my overlay objects are falling into which does not seem correct according to my understanding of how things should be working. It appears the overlay objects with mask "overlay" are getting compared against mask "Default", the code then updates that object to the comparing layer, in other words it sets the thing that was on layer "overlay" to layer "Default". This ultimately creates an input issue because now everything that was in the "overlay" layer stops receiving those events.

This seems odd? Am I missing something here?

Thanks!

PS I have GIT access, I updated to commit 64159ca (Feb 23, 2014 3:25PM) after I hit this issue but its still occuring

ArenMook

  • Administrator
  • Hero Member
  • *****
  • Thank You
  • -Given: 337
  • -Receive: 1171
  • Posts: 22,128
  • Toronto, Canada
    • View Profile
Re: Dynamically adding a prefab under a UICamera resets all layers to default
« Reply #1 on: February 24, 2014, 03:12:34 PM »
All widgets beneath a panel adopt the panel's layer. So if your panel is on the Default layer, all widgets underneath will also be on the Default layer.

This is done for consistency, because UIPanel is what draws things, so only its layer matters for drawing -- however in case of events, the layer of the widget is what controls whether the widget receives events or not.

NGUI simply forces them to be the same.

You need to use NGUITools.AddChild(parent, prefab) to instantiate children. It sets the layers for you among other things.

Nicki

  • Global Moderator
  • Hero Member
  • *****
  • Thank You
  • -Given: 33
  • -Receive: 141
  • Posts: 1,768
    • View Profile
Re: Dynamically adding a prefab under a UICamera resets all layers to default
« Reply #2 on: November 04, 2014, 05:32:47 AM »
I ran into some problems related to this, so I wanted to raise the issue again.

  1. void UpdateLayers ()
  2.         {
  3.                 // Always move widgets to the panel's layer
  4.                 if (mLayer != cachedGameObject.layer)
  5.                 {
  6.                         mLayer = mGo.layer;
  7.                         NGUITools.SetChildLayer(cachedTransform, mLayer);
  8.                         ResetAnchors();
  9.  
  10.                         for (int i = 0; i < drawCalls.Count; ++i)
  11.                                 drawCalls[i].gameObject.layer = mLayer;
  12.                 }
  13.         }
  14.  

NGUITools.SetChildLayer is entirely indiscriminate in which children have their layers changed, not just widgets. This seems to be a mistake, as certain setups can have a somewhat intricate setup of layers.

Personally, I'm running into problems with having to switch layers around during an animation and having inactive 3d elements inside the hierarchy in different layers. This makes the UIPanel screw up my layer setup since it completely blasé sets every child under it to a different layer. If you instantiate something with a panel inside it that is inactive, this method will also mess with the layering of that, which feels like a flaw.

Isn't the whole UpdateLayers redundant when the UIWidget has its own CheckLayer, which as far as I can see does the same thing?

For now I'm just commenting out the NGUITools.SetChildLayer since, as far as I can see, it's not needed anyway, I'm just loathe to change NGUI source without pull requesting it, so I just wanted to hear if there's some logic that I'm not seeing behind it. :)

ArenMook

  • Administrator
  • Hero Member
  • *****
  • Thank You
  • -Given: 337
  • -Receive: 1171
  • Posts: 22,128
  • Toronto, Canada
    • View Profile
Re: Dynamically adding a prefab under a UICamera resets all layers to default
« Reply #3 on: November 04, 2014, 10:28:41 AM »
This check is for when you change the panel's layer for any reason. It doesn't come into play unless the layer actually changes. It's set in Start(), so prior to it being used.

Nicki

  • Global Moderator
  • Hero Member
  • *****
  • Thank You
  • -Given: 33
  • -Receive: 141
  • Posts: 1,768
    • View Profile
Re: Dynamically adding a prefab under a UICamera resets all layers to default
« Reply #4 on: November 04, 2014, 05:45:51 PM »
Well the tricky bit is that I do change the layer, but I want to keep control of it myself, so I can change it back. It's for a momentary animation, where there are some 2d and 3d that need to layer just right. Changing it, makes the panel change other things to its own layer - I mean, I could live with it changing all widgets registered to it (since that logically makes sense), but it just changes everything under its hierarchy which, at least to me, seems like solving a fairly rare corner case with a giant cannon.