Author Topic: UIPanel is attaching unexpectly  (Read 4657 times)

Ivian

  • Newbie
  • *
  • Thank You
  • -Given: 1
  • -Receive: 0
  • Posts: 5
    • View Profile
UIPanel is attaching unexpectly
« on: August 27, 2013, 08:15:46 AM »
Hi all ;)

I was searching the forums, but i can't find any topic connected with my issue.
I've made a big update of NGUI today (it's been ~half year). And the problem is with my prefabs that are groups of widgets:

The case:
I'm making a window with 4 scrolled lists. But only one of them is visible, so u can change the lists by swiping them on sides.
Those lists are generated in runtime:
I've made a prefab(one entry of list, which u can select) with some widgets I'm filling at runtime (screen). There are labels and sprites. Nothing complicated. The root of prefab is a void GameObject with the constructor script attached. Everything worked fine until I've made an update:

Now during instantiate (in editor and in play mode) to the instantiated prefab an UIPanel is attached(screens) , which ruins the clipping of the higher hierarchy UIPanels(screen). There is no warning, so i can't even dig to the code to check out what's goin' on.

NOTE:
If i manualy delete the UIPanel component during runtime everything still works fine. But I want to make those scripts as effective and fast as they could be, so I want to avoid the unattaching.

Regards




Ivian

  • Newbie
  • *
  • Thank You
  • -Given: 1
  • -Receive: 0
  • Posts: 5
    • View Profile
Re: UIPanel is attaching unexpectly
« Reply #1 on: August 27, 2013, 09:25:09 AM »
Ok so there is a quick solution i came up with:

When object is created in the setter of material in UIWidget the UIWidget::CreatePanel() is invoked, which invokes the UIPanel::Find(Transform,bool). The bool stands for "createIfMissing" and is set to true, so the panel is created. What's going on is: When you are creating a gameObject he does not have a parent, so he breaks the loop
  1.                 while (panel == null && trans != null)
  2.                 {
  3.                         panel = trans.GetComponent<UIPanel>();
  4.                         if (panel != null) break;
  5.                         if (trans.parent == null) break;
  6.                         trans = trans.parent;
  7.                 }
And UIPanel is attached. The point is, that game object is parented a line later.
The bug (IMHO) is that code attaches UIPanel, even the Camera or UIRoot was not foud during resarch. (I can't find why one would need an UIPanel not beeing in the hierarchy of UIRoot. So there is an hotfix to the UIPanel.cs:
  1.         static public UIPanel Find (Transform trans, bool createIfMissing)
  2.         {
  3.                 Transform origin = trans;
  4.                 UIPanel panel = null;
  5.         UICamera cam = null;
  6.        
  7.                 while (panel == null && trans != null)
  8.                 {
  9.             panel = trans.GetComponent<UIPanel>();
  10.             if (panel != null) break;
  11.             else
  12.                 if (cam == null) cam = trans.GetComponent<UICamera>();
  13.                         if (trans.parent == null) break;
  14.             trans = trans.parent;
  15.                 }
  16.  
  17.         if (createIfMissing && panel == null && cam != null && trans != origin)
  18.                 {
  19.                         panel = trans.gameObject.AddComponent<UIPanel>();
  20.                         SetChildLayer(panel.cachedTransform, panel.cachedGameObject.layer);
  21.                 }
  22.                 return panel;
  23.         }
But I'm still pretty intrested why is this needed? :)

Greetings ;)

ArenMook

  • Administrator
  • Hero Member
  • *****
  • Thank You
  • -Given: 337
  • -Receive: 1171
  • Posts: 22,128
  • Toronto, Canada
    • View Profile
Re: UIPanel is attaching unexpectly
« Reply #2 on: August 27, 2013, 12:18:05 PM »
Panels get attached if none gets found. Most common cause is using Instantiate instead of NGUITools.AddChild, and then trying to modify something before setting the parent.

UIPanel can be not in the UI hierarchy in case of in-world GUIs. UIRoot and anchor are not essential components.