Author Topic: What is the correct way to re-position a widget?  (Read 5653 times)

bkinsey

  • Newbie
  • *
  • Thank You
  • -Given: 2
  • -Receive: 1
  • Posts: 30
    • View Profile
What is the correct way to re-position a widget?
« on: September 16, 2014, 11:59:59 PM »
I have a prefab widget called a "FloatingScreenNotification".  It's a pretty simple structure:

  1. UIWidget
  2.     Label
  3.     Sprite
  4.  

The widget, when created, uses Tweens to float upward, displaying a message, for example: "+1 [gold icon]"

The widget works as expected. However, when I create an instance of this prefab, and try to set its position, it is always drawn in the same exact position..
  1.                 GameObject go = Instantiate (FloatingScreenNotificationPrefab, new Vector3(-290, -272, 0), Quaternion.identity) as GameObject;
  2.  
  3.                 FloatingScreenNotification n = go.GetComponent<FloatingScreenNotification> ();
  4.  
  5.                 n.Label.text = "+" + amount.ToString ();
  6.                 n.Sprite.enabled = false;
  7.  
  8.                 //UIWidget widget = n.Widget;
  9.                 //widget.SetRect (-290, -272, widget.width, widget.height);
  10.  

-290, -272 is supposed to be at the bottom left of the screen. The widget was created in the middle of the screen, made into a prefab, and removed from the scene.

I've tried setting the GameObject's transform properties, supplying a position in the Instantiate function, and using the SetRect method, and nothing changes visually, the notification is always appearing at the middle of my screen and floating upwards. Is it supposed to be this hard to re-position a UI element during runtime? :(

ArenMook

  • Administrator
  • Hero Member
  • *****
  • Thank You
  • -Given: 337
  • -Receive: 1171
  • Posts: 22,128
  • Toronto, Canada
    • View Profile
Re: What is the correct way to re-position a widget?
« Reply #1 on: September 17, 2014, 12:33:24 PM »
Never use Instantiate. Use NGUITools.AddChild. Look inside the function to find out why.

^
|
|
I had to say that so many times I have it copy/pasted.

bkinsey

  • Newbie
  • *
  • Thank You
  • -Given: 2
  • -Receive: 1
  • Posts: 30
    • View Profile
Re: What is the correct way to re-position a widget?
« Reply #2 on: September 17, 2014, 10:51:16 PM »
I ended up doing the same thing as your function, well almost. (now I do :D)

But, if I don't use instantiate, it means I can't use prefabs?  The function looks like it creates a child GameObject for me, and then I'm supposed to programmatically add components?

My first problem was that the Position Tween uses absolute values and not related, which makes sense, but it was instantly teleporting my widget.  I also saw that it wasn't drawing correctly unless I called the Panel.AddWidget API.  Here is my solution, seems to be working:

  1.                 GameObject go = Instantiate (FloatingScreenNotificationPrefab) as GameObject;
  2.  
  3.                 Transform t = go.transform;
  4.                 t.parent = gameObject.transform;
  5.                 t.localPosition = new Vector3 (-240, -235, 0);
  6.                 t.localRotation = Quaternion.identity;
  7.                 t.localScale = Vector3.one;
  8.                 go.layer = gameObject.layer;
  9.  
  10.                 FloatingScreenNotification n = go.GetComponent<FloatingScreenNotification> ();
  11.  
  12.                 n.Label.text = "+" + amount.ToString ();
  13.                 n.Sprite.enabled = false;
  14.  
  15.                 TweenPosition p = n.TweenPosition;
  16.                 p.SetStartToCurrentValue ();
  17.                 p.to = p.from;
  18.                 p.to.y += 60;
  19.                 p.enabled = true;
  20.  
  21.                 UIWidget w = n.Widget;
  22.                 Panel.AddWidget (w);
  23.  

ArenMook

  • Administrator
  • Hero Member
  • *****
  • Thank You
  • -Given: 337
  • -Receive: 1171
  • Posts: 22,128
  • Toronto, Canada
    • View Profile
Re: What is the correct way to re-position a widget?
« Reply #3 on: September 18, 2014, 03:24:35 PM »
Why can't you use prefabs?
  1. GameObject instance = NGUITools.AddChild(parentObject, prefab);
The key here is 'parentObject' is somewhere in your UI, so you aren't just creating a random UI element in the middle of nowhere. All UI elements need to be parented to a panel at the very least. If they aren't, they attempt to find a parent instead, and may not find the right one. Always specify the right parent to be safe. If you don't have a parent, just use UIRoot.list[0].gameObject.

P.S. NEVER use panel.AddWidget yourself. This is plain wrong.

bkinsey

  • Newbie
  • *
  • Thank You
  • -Given: 2
  • -Receive: 1
  • Posts: 30
    • View Profile
Re: What is the correct way to re-position a widget?
« Reply #4 on: September 19, 2014, 01:21:58 AM »
Ah, didn't see the overloads, my mistake.

Ok so I am using NGUITools.AddChild, but there is no corresponding RemoveChild API.  The GameObject will delete itself, and in that case, when the panel iterates through children to draw, it finds a null one and says "This should not happen!".  I added a call Panel.RemoveWidget(...) prior to destruction of my UI game object and no longer get any complaints/errors.. is this the right way to cleanup a UI control from the hierarchy?

Nicki

  • Global Moderator
  • Hero Member
  • *****
  • Thank You
  • -Given: 33
  • -Receive: 141
  • Posts: 1,768
    • View Profile
Re: What is the correct way to re-position a widget?
« Reply #5 on: September 19, 2014, 06:46:16 PM »
Removing the child is just a matter of destroying the gameobject, then the UIpanel will take care of the rest.

Adding is just a matter of AddChilding the widget gameobject to the panel or somewhere in the hierarchy under the panel, then it also handles itself.

As for setting the position:
  1. var go = NGUITools.AddChild(theParentObject, MyPrefab);
  2. go.transform.localPosition = new Vector3(100,0,0); //pixels.
  3.  
  4. //and even
  5. var tween = TweenPosition.Begin(go,1f,new Vector(-100,0,0);
  6. tween.method = UITweener.Method.EaseInOut; //peasants use linear. Be a king instead!
  7.  

http://www.tasharen.com/ngui/docs/class_tween_position.html

The reason you set the position after resetting scale and rotation to identity vectors, is that it otherwise would offset with those two respectively.

ArenMook

  • Administrator
  • Hero Member
  • *****
  • Thank You
  • -Given: 337
  • -Receive: 1171
  • Posts: 22,128
  • Toronto, Canada
    • View Profile
Re: What is the correct way to re-position a widget?
« Reply #6 on: September 19, 2014, 08:47:30 PM »
Ok so I am using NGUITools.AddChild, but there is no corresponding RemoveChild API.
NGUITools.Destroy