Tasharen Entertainment Forum

Support => NGUI 3 Documentation => Topic started by: ArenMook on December 06, 2013, 06:09:05 PM

Title: UIRect
Post by: ArenMook on December 06, 2013, 06:09:05 PM
Overview

UIRect is the base component that both Widgets (http://www.tasharen.com/forum/index.php?topic=6702.0) and Panels (http://www.tasharen.com/forum/index.php?topic=6705.0) derive from. You won't be able to create it as a component it as it's an abstract class. Instead, create a Widget or a Panel if you want something tangible.

Video that shows the different anchor types in action:
http://www.youtube.com/watch?v=P8JTTE0JBXQ

(http://www.tasharen.com/ngui/anchor.jpg)

All NGUI elements that have a modifiable area can be anchored to other elements or even 3D objects. When choosing an anchor point, you can decide whether you want all sides to be anchored to the same object, or different ones. Choosing Unified will give you one option, while going with Advanced will give you one per side.

To anchor a widget, move it in the desired position, choose one of the presets, and drag & drop the Target you want it to be anchored to. The anchor's values will be filled in automatically.

To set up a widget inside to always be "inset" in another widget, make it a child of that widget then choose the Unified option. The target widget will be picked up automatically and the initial values will be filled in for your convenience. You can then further adjust the widget either in the scene view like you normally would, or by modifying the options.

Each side is anchored independently of the others, and for each you get to choose which of the 3 preset anchor points it will use. For example for Left and Right, they are Left, Center, and Right. If neither suit your needs, choose Custom and set the values yourself.

(http://www.tasharen.com/ngui/anchorunified.jpg)

Custom setting gives you a Relative value to work with. This value is relative to the target's dimensions, and as such will only be selectable when you are targeting another widget or a panel as the Target.

With a Left or Right anchor, 0 means left, 1 means right, and 0.5 means right down the middle. 0.25? 25% of the target's width from the target's left.

Choosing "Set to Current Position" will simply set the anchor point to where the side is currently positioned, making the offset be zero.

(http://www.tasharen.com/ngui/anchoradvanced.jpg)

If you want more control, or if you want to anchor only specific sides, then Advanced anchor type is what you should go with. With Advanced mode you can specify unique targets for each anchor point, effectively controlling which sides will be adjusted by the anchors, and which ones will remain as you left them. In the picture above I did just that for the slider's thumb: I chose padded anchors for the Top and Bottom, making them resize as the slider's height changes, but I left Left and Right as None. This means that resizing the slider horizontally won't affect the thumb.

You can examine this further by dragging in the Simple Horizontal Slider control into your scene and selecting its thumb.

(http://www.tasharen.com/ngui/anchortransform.jpg)

Last but not least, you don't need to specify widgets or panels as the Target. You could also specify a random game object of your choice in order to make the UI widget follow it. If your rectangle is on a widget, you can also make it automatically hide itself it it detects that it's no longer visible. Since the alpha is cumulative, doing so will automatically affect all of its children.

Class Documentation

http://tasharen.com/ngui/docs/class_u_i_rect.html

If you have a question regarding this component or would like me to clarify something, just post a reply here.
Title: Re: UIRect
Post by: dominus85 on December 08, 2013, 06:08:42 AM
This appears to be making stretch and anchor obsolete..

However it doesn't cover for the scenario when you need a to keep proportions.. think of a background that needs to be resized keeping aspect ration, without stretching
Title: Re: UIRect
Post by: zippo227 on December 14, 2013, 05:07:02 PM
How can I programmatically assign an object target to an anchor?

Well, after some tries. If you assign all of the anchors, then you can get a unified anchor. It would be easier to set the type and then set only one anchor, but this works OK.

  1.                
  2. label.topAnchor.target = obj.transform;
  3. label.bottomAnchor.target = obj.transform;
  4. label.rightAnchor.target = obj.transform;
  5. label.leftAnchor.target = obj.transform;
  6. label.leftAnchor.absolute = -25;
  7. label.rightAnchor.absolute = 25;
  8. label.topAnchor.absolute = 32;
  9.  
Title: Re: UIRect
Post by: ArenMook on December 14, 2013, 07:27:17 PM
"Unified" is just a simplified way of visualizing the same data. When all 4 anchor targets match, they get "unified" into one.
Title: Re: UIRect
Post by: Meltdown on January 26, 2014, 01:17:49 AM
This appears to be making stretch and anchor obsolete..

However it doesn't cover for the scenario when you need a to keep proportions.. think of a background that needs to be resized keeping aspect ration, without stretching

It took me many hours to figure how to do this. Michael you may want to add this to an updated video to avoid confusion and frustration.

With the new Anchor system, I kept finding that my sprites would re-size at different camera aspect ratios, and not stay in the same aspect ratio as I had them initially.

To fix this, you need to use the following settings for a sprite you want to anchor in the top left...

Anchor Type : Unified
Left : Target's left
Right : Target's left (Note : since we want to anchor to the left side, this is set left as well)
Top : Target's top
Bottom : Target's top (Note : since we want to anchor to the top side, this is set top as well)

So for the side you want to anchor to, make sure the opposite sides are set to those sides as well, otherwise NGUI will try to stretch your sprites!
Title: Re: UIRect
Post by: honeal on March 20, 2014, 06:25:47 PM
ArenMook can you please add the "Run Only Once" functionality back into the new anchoring system? I've made the code change myself, but don't want to have to stop updating NGUI to keep from breaking it. It was a quick change, and I'm sure others will find just as much value in it.
Title: Re: UIRect
Post by: ArenMook on March 21, 2014, 04:52:09 PM
Done. You will find it in the next update.
Title: Re: UIRect
Post by: honeal on March 24, 2014, 03:45:18 PM
Fantastic. Thank you!
Title: Re: UIRect
Post by: Bobbin on March 30, 2014, 11:36:22 AM
Can I give UIRect a delegate to run after all the anchors have been updated?
Title: Re: UIRect
Post by: ArenMook on March 30, 2014, 03:04:32 PM
UIWidget.onChange delegate is triggered when the widget is moved for any reason -- you can use that if you like.
Title: Re: UIRect
Post by: Bobbin on March 31, 2014, 02:39:15 AM
That seems to work better. Thanks.
Title: Re: UIRect
Post by: tayl0r on April 30, 2014, 04:10:25 PM
I have a widget with it's anchor set to "Execute: OnEnable". I move the widget by setting its localPosition. The next frame it snaps back to the anchor position.

I thought if the execute type is set to OnEnable it wouldn't be doing this.

I thought that maybe I could just turn the anchor off, but looking in UIRect.cs it's not clear how to do that. It looks like you need to set each anchor target to null but it doesn't seem like UIRect wants us to do that.

How should I be doing this? I don't want to put the widget in a panel and move the panel, I just want to position the widget via the anchor in the editor, have the game start and have its position set via the anchor, then move it around later via code.

I also want to clone that widget (Instantiate(widget)) and move the instantiated widget around as well, so in that case I think I probably do need to disable the anchoring since I don't want it to run even once.

Edit: it looks like SetAnchor(null); does the trick!
Title: Re: UIRect
Post by: ArenMook on April 30, 2014, 06:04:08 PM
Don't use Instantiate. Use NGUITools.AddChild.

OnEnable still does it in Update, but only once, so if you change the position immediately after instantiation, then you are doing it before it runs.

SetAnchor(null) will indeed clear it.
Title: Re: UIRect
Post by: Bobbin on May 14, 2014, 07:02:10 AM
Is there a way for me to set a UIRect's anchor just like Advanced in the inspector but from code?

I assume that target is the transform to anchor to and absolute is the offset but how do I choose "Right Anchor to Target's Right" or something like that?
Title: Re: UIRect
Post by: ArenMook on May 14, 2014, 07:07:13 AM
"Unified" is just a shortcut for visualization. It means that all 4 anchor values reference the same object.

UIRect has SetAnchor() letting you choose an unified anchor, or you can set each anchor individually via UIRect's leftAnchor, rightAnchor, etc. Don't forget to call ResetAnchors() and UpdateAnchors() afterwards.
Title: Re: UIRect
Post by: Bobbin on May 14, 2014, 07:08:11 AM
Ok.
But how do I know which side of the target the anchor attaches to?
Title: Re: UIRect
Post by: ArenMook on May 14, 2014, 07:17:05 AM
widget.leftAnchor.relative = 0f; <-- left for horizontal anchors (bottom for vertical)
widget.leftAnchor.relative = 1f; <-- right for horizontal anchors (top for vertical)
widget.leftAnchor.relative = 0.5f; <-- center
widget.leftAnchor.relative = 0.25f; <-- 25% from the left, etc.
Title: Re: UIRect
Post by: Bobbin on May 14, 2014, 07:20:27 AM
So the absolute value of the AnchorPoint is a flag of sorts and I need the relative for offset?
Uhm... looking at UIRect.cs, I think it's the other way around.
Title: Re: UIRect
Post by: ArenMook on May 14, 2014, 07:22:56 AM
Yes, relative is what I meant. Final position = Parent's width or height * relative + absolute.
Title: Re: UIRect
Post by: Bobbin on May 14, 2014, 07:24:01 AM
Excellent. Thank you.
Title: Re: UIRect
Post by: honeal on May 15, 2014, 07:39:42 PM
ArenMook, have you given any thought to adding a max/min width/height option to UIWidget similar to the native Android layout system? I find myself missing that functionality quite often when designing for multiple screens.
Title: Re: UIRect
Post by: toto007 on May 16, 2014, 03:55:50 AM
I'm trying to understand what it means to activate the voice Execute: "onEnable."

I imagine that the anchoring is done only when the widget is enabled. So I try to manually move the object on the scene after it has been activated but remains fixed and does not move.

Why?

Don't use Instantiate. Use NGUITools.AddChild.

OnEnable still does it in Update, but only once, so if you change the position immediately after instantiation, then you are doing it before it runs.

SetAnchor(null) will indeed clear it.
Title: Re: UIRect
Post by: ArenMook on May 16, 2014, 03:03:58 PM
"OnEnable" means it's updated once -- after the widget is first enabled. After that the anchor will not be updating, so moving the target object won't move the anchored widget. "OnUpdate" means it will update every Update call (every frame), so it will always track the target's movement.
Title: Re: UIRect
Post by: RDeluxe on May 29, 2014, 06:08:14 PM
Hi !

Edit : I posted the question here (http://www.tasharen.com/forum/index.php?topic=9737.0)
Title: Re: UIRect
Post by: hojjatjafary on February 07, 2016, 07:24:58 AM
Does the anchoring supports chaining? I have 4 buttons from left to right in a row [A B C D], I anchored B's left to A's right and so on.

Size of buttons change at runtime according to their label size, because labels are localized strings, the size of labels set to widget size using a property binding component.

but seems this depends on the order of calling update by Unity.
Title: Re: UIRect
Post by: ArenMook on February 08, 2016, 01:59:54 AM
Yes, it should work fine with chained elements assuming the anchors are set to update in Update rather than OnEnable/OnStart, although I would caution you to use that sparingly. Anchoring calculations can quickly add up to become expensive. Also note that if you have nested elements, anchoring can become unpredictable when your anchored objects happen to result in a child element being moved that already completed its anchoring calculations. The way it works is when NGUI does an update it checks -- has the widget that the current one is anchored to completed its anchoring calculations? If not, the pre-requisite widget's anchoring code is ran first. It's nested.
Title: Re: UIRect
Post by: skatola on May 29, 2016, 11:41:51 AM
excuse me...there's a way to execute anchors in runtime?
for example if i set anchors execute "on start" and i need to execute again in runtime, how can i do that? thanks a lot like always
Title: Re: UIRect
Post by: ArenMook on May 29, 2016, 11:50:16 AM
That would be the OnUpdate setting.
Title: Re: UIRect
Post by: skatola on May 29, 2016, 03:33:11 PM
That would be the OnUpdate setting.

but i don't want to update the anchors every frame, but only when i want, there's no way to update anchors via script?
try to explain it better:
i have a 2d ui texture on screen in full screen, anchored to camera for take the fullscreen and with fixed aspect enabled for manteining img ratio, when i rotate the device the image appear small in the center of the screen, i just want recalculate the anchors to adapt the texture in full screen with the new device orientation.
sorry for my english, hope it is understandable : )
Title: Re: UIRect
Post by: ArenMook on June 01, 2016, 10:43:01 PM
UIRect.UpdateAnchors(). Check first, ask later. :P