Author Topic: How can I anchor without stretching now?  (Read 4877 times)

PaulGregory

  • Guest
How can I anchor without stretching now?
« on: December 08, 2013, 06:17:03 PM »
Right then. Thought I'd update my UI to use the new anchoring system in 3.0.7, and make them more consistent at the same time.

I've ran into an issue. It seems anchoring and stretching have become one.

My UI design - based on an earlier NGUI example - has various 'cards' that animate in and out for different sections of the menu.

The cards have a strip at the top (UISprite), and a line of text for the card title (UILabel).
Each card has a background UISprite.
The cards themselves have differing widths and heights depending on how much content they have.

I would like the strip to be anchored at the top of the card, and run the full width of the card.

However, I would like all the strips to be the same height as each other.

The new anchoring is great at making my card title (UILabel) fit in the middle of my UISprite.

Unfortunately, I can't see how I *stop* stretching when I don't want it.
EDIT: Now I can see how I specify a size, which is good enough. See below

Let's say I want all my top stripes to be 50px tall.

With Anchors set to...

None: I can simply set the Y Dimension of my UISprite to 50 - but I need to enter the correct X dimension and set the Y transform position manually so it is at the top of my 'card'. I can work this all out based on the card size, but I'd prefer to use anchoring.

Padded, and a target of the card UISprite (which happens to be 500 tall), the settings are automatically worked out as being left 0, right 0, bottom 450, top 0. I'm therefore specifying the amount of pixels that are *not* taken up by the strip - the margin sizes, not the content size. Meaning that if I made the card bigger, I'd need to recalculate that bottom if I want the stripe to stay at 50px tall and not stretch in height with the card.

Relative, everything is explicitly based upon multiples of the target's size. Fine in the X dimension but not the Y.

Unified, I can mix and match between setting things as a multiple of the target or by a pixel margin.
EDIT: And I can set minus margins, if I set the right target multiplier! Woo. This is the solution.

Advanced, I can change things like I can in Unified except I can change the target for each side.

With any of these Anchor modes on, I can no longer set the Y Dimension - it springs back to the value calculated by the anchoring. So anchoring and stretching have been combined. This has many uses, but doesn't help this situation.

I do want to position and stretch in the X dimension, but I only want to position in the Y. I want to specify the height of the sprite and not have it changed by Anchoring.

I know I can design my background UISprite to include the top strip in the slicing, which would be represented faithfully in a specific number of pixels. But then I would be faced with the problem of getting my UILabel to anchor in the middle of the top strip without stretching.

The item that my scaling is a multiple of and the item to which I am anchoring are not always going to be the same thing, but it seems Anchors assumes it is. Am I missing something?
« Last Edit: December 08, 2013, 07:29:32 PM by PaulGregory »

PaulGregory

  • Guest
Re: How can I anchor without stretching now?
« Reply #1 on: December 08, 2013, 06:27:47 PM »
*looks at pictures in UIRect documentation*

Ah..

Padded does not work with negatives, but Unified does.

If I use Unified I can set both top and bottom to 1* and the Bottom + to -50 and I can achieve what I want to achieve.

I've figured out a way of explaining this to myself which is clearer than the current documentation, and I'll add that here in a mo.
« Last Edit: December 08, 2013, 06:49:08 PM by PaulGregory »

ArenMook

  • Administrator
  • Hero Member
  • *****
  • Thank You
  • -Given: 337
  • -Receive: 1171
  • Posts: 22,128
  • Toronto, Canada
    • View Profile
Re: How can I anchor without stretching now?
« Reply #2 on: December 08, 2013, 07:27:52 PM »
Padded is just a simplified representation that assumes that left and bottom have relative values of 0, and top and right have values of 1. Unified lets you tweak them, and do things like specifying 0.5 to indicate "center".

PaulGregory

  • Guest
Re: How can I anchor without stretching now?
« Reply #3 on: December 08, 2013, 07:49:55 PM »
Yes but the whole thing now assumes you either want to stretch things or specify a size. There's no way to position something of unknown size without stretching it.

EDIT: Oh, yes, Advanced and then set something to no target.

In making widgets and panels more explicitly a rectangle you are requiring us to care where each edge is. The old Anchor gave the appearance of only caring about one or two edges.

I can see however, that the new system will be more efficient, even if it is a bit non-intuitive.

My explanation of how I now understand the Anchors Unified options is now in the UIRect thread:
http://www.tasharen.com/forum/index.php?topic=7013.msg33172#msg33172

PaulGregory

  • Guest
Re: How can I anchor without stretching now?
« Reply #4 on: December 08, 2013, 08:02:11 PM »
OK, I've switched to Advanced and taken the target off Bottom.

If I try to change the Widget Y dimension in the Inspector, it automatically changes to a different number.
If I have a Top anchor target but not a Bottom, why is it resizing?

ArenMook

  • Administrator
  • Hero Member
  • *****
  • Thank You
  • -Given: 337
  • -Receive: 1171
  • Posts: 22,128
  • Toronto, Canada
    • View Profile
Re: How can I anchor without stretching now?
« Reply #5 on: December 09, 2013, 12:51:39 AM »
No anchor means "leave the edge where it is".

You can still use the old anchors if they suit your usecase better.

Also keep in mind you don't have to anchor to other widgets and their edges. You can anchor to any game object, and then there will be no edges.

P.S. Next update will let you resize anchored widgets freely.

PaulGregory

  • Guest
Re: How can I anchor without stretching now?
« Reply #6 on: December 09, 2013, 12:07:07 PM »
Are you saying that's a bug, or is having this scaled to 100% a really abnormal usecase?

'Advanced' would be great if having no anchor on one side meant that the side was positioned based on the widget size, but it doesn't seem reliable at present.

I think there is a need for an anchor type that doesn't involve any scaling (or invisibly calculates the scaling based on the widget size), as there are many usecases for that.

I appreciate I can still use the old anchor scripts, but basing my UI on items marked deprecated does not feel right. It's not like the old anchors didn't have problems.

I haven't tried anchoring to game objects that aren't NGUI objects yet. I'm confused by the idea that game objects don't have edges - is anchoring based on the object's centre?

ArenMook

  • Administrator
  • Hero Member
  • *****
  • Thank You
  • -Given: 337
  • -Receive: 1171
  • Posts: 22,128
  • Toronto, Canada
    • View Profile
Re: How can I anchor without stretching now?
« Reply #7 on: December 09, 2013, 01:38:11 PM »
I took some of your feedback into consideration when doing a simplification pass:

http://www.youtube.com/watch?v=P8JTTE0JBXQ

PaulGregory

  • Guest
Re: How can I anchor without stretching now?
« Reply #8 on: December 09, 2013, 02:16:59 PM »
That is a great improvement, thanks.

It also now looks much more straightforward to anchor one widget's top to another widget's bottom.

ArenMook

  • Administrator
  • Hero Member
  • *****
  • Thank You
  • -Given: 337
  • -Receive: 1171
  • Posts: 22,128
  • Toronto, Canada
    • View Profile
Re: How can I anchor without stretching now?
« Reply #9 on: December 09, 2013, 04:07:05 PM »
:)