Author Topic: Having weird problems setting anchors in code. Is this a bug??  (Read 3877 times)

0xbdf

  • Newbie
  • *
  • Thank You
  • -Given: 0
  • -Receive: 0
  • Posts: 6
    • View Profile
Hey everyone,

I'm setting the anchors of a sprite dynamically with the following code:

  1.         void TargetTile(UIWidget tile)
  2.         {
  3.                 horizontal.gameObject.SetActive(true);
  4.                 vertical.gameObject.SetActive(true);
  5.  
  6.                 vertical.leftAnchor = tile.leftAnchor;
  7.                 vertical.rightAnchor = tile.rightAnchor;
  8.  
  9.                 horizontal.topAnchor = tile.topAnchor;
  10.                 horizontal.bottomAnchor = tile.bottomAnchor;
  11.         }
  12.  

Context:
  • "vertical" and "horizontal" are both UISprites
  • The feature is a placement crosshairs. We have a grid of tiles, and the player's finger is dragging over them. As they drag, these horizontal and vertical sprites snap to the row and column, indicating the tile the player is on if they release that moment.

THE PROBLEM

The positioning of the UISprites ends up correct, but their size is incorrect: their edges don't match to the edges of the widgets I'm aligning them with. Rather, they'll be centered around the widget, and will have an absolute width.

"Absolute width" meaning that when the screen is smaller, Horizontal is taller and Vertical is wider, taking up the same number of pixels. The same is not true of the objects I'm using to set the anchors. This is almost as if it's working from an absolute frame of reference that doesn't change in size as the screen does. This makes no sense though, as its frame of reference is the same as the object I'm using to set its anchors.

When I pause the game and look at the properties in the inspector, everything looks good. The targets are correct, as are the relative and absolute offsets.

----

TLDR: The same properties on the anchors of the objects being set and their references are behaving differently. To confound me further, it works APPROXIMATELY correctly, but wrong enough to be a major problem for the feature.

I'm absolutely baffled by this. It makes so little sense, it seems like a bug. Can anything be done?

ArenMook

  • Administrator
  • Hero Member
  • *****
  • Thank You
  • -Given: 337
  • -Receive: 1171
  • Posts: 22,128
  • Toronto, Canada
    • View Profile
Re: Having weird problems setting anchors in code. Is this a bug??
« Reply #1 on: April 26, 2014, 02:27:41 PM »
You are changing references to anchors here. The anchor is a class, not a struct. All class assignments in C# change the actual reference. They don't copy the values. You basically have two widgets using the same anchors now.

You need to use the SetAnchor() function, or change anchor.absolute + anchor.relative values like you see happening inside the UIRect.SetAnchor function.

0xbdf

  • Newbie
  • *
  • Thank You
  • -Given: 0
  • -Receive: 0
  • Posts: 6
    • View Profile
Re: Having weird problems setting anchors in code. Is this a bug??
« Reply #2 on: April 26, 2014, 06:31:59 PM »
Thank you very much for the help. I'm seeing the exact same issue, however.

I've now tried setting the anchor's values both by copying the relevant values and by recalculating them.

Same result:
  • Anchor values are correct (ie. identical to the Tile's and calculated desired values)
  • Assets are CENTERED around the correct position
  • Assets don't SIZE according to their anchors, keeping absolute size on the screen regardless of the "Game" window's size. Most of the time, they're larger than they should be.

Code:
  1.         void TargetTile(UIWidget tile)
  2.         {
  3.                 horizontal.gameObject.SetActive(true);
  4.                 vertical.gameObject.SetActive(true);
  5.  
  6.                 vertical.leftAnchor.relative = tile.leftAnchor.relative;
  7.                 vertical.rightAnchor.relative = tile.rightAnchor.relative;
  8.  
  9.                 horizontal.topAnchor.relative = (float)tile.GetComponent<Tile>().y / 6f;
  10.                 horizontal.bottomAnchor.relative = (float)(tile.GetComponent<Tile>().y + 1) / 6f;
  11.                
  12.                 //vertical.leftAnchor = tile.leftAnchor;
  13.                 //vertical.rightAnchor = tile.rightAnchor;
  14.                 //horizontal.topAnchor = tile.topAnchor;
  15.                 //horizontal.bottomAnchor = tile.bottomAnchor;
  16.         }
  17.  

Behavior is UNCHANGED from the commented out code, and my previous post. Could this be caused by something other than a reference issue?

0xbdf

  • Newbie
  • *
  • Thank You
  • -Given: 0
  • -Receive: 0
  • Posts: 6
    • View Profile
Re: Having weird problems setting anchors in code. Is this a bug??
« Reply #3 on: April 26, 2014, 06:39:59 PM »
Here's a really clean illustration of the same thing:

When I use SetAnchor(), and I just set it to the object it's already anchored to and don't change any of the other properties, the values shown while the game is running indicate that the object I'm setting IS flush with the one I'm anchoring it to, and yet the sizes of the objects very clearly AREN'T.

Also, the relative sizes changes (though the anchors don't) if I change the size of the game window.

ArenMook

  • Administrator
  • Hero Member
  • *****
  • Thank You
  • -Given: 337
  • -Receive: 1171
  • Posts: 22,128
  • Toronto, Canada
    • View Profile
Re: Having weird problems setting anchors in code. Is this a bug??
« Reply #4 on: April 27, 2014, 11:34:09 PM »
Your code copies the relative and absolute values, but where is the code that actually sets the anchoring? Do you actually have one widget anchored to another? Because this is not shown here. Furthermore I am not sure what this "Tile" is, or what values you get from doing your math there.

Why are you doing any of this in the code anyway? Why can't you set it up in inspector?

0xbdf

  • Newbie
  • *
  • Thank You
  • -Given: 0
  • -Receive: 0
  • Posts: 6
    • View Profile
Re: Having weird problems setting anchors in code. Is this a bug??
« Reply #5 on: April 29, 2014, 03:06:13 PM »
Answers inline below. Screenshot of inspector and the problem attached:

Quote
Your code copies the relative and absolute values, but where is the code that actually sets the anchoring?
The anchor targets are set in the object hierarchy. "horizontal" and "vertical" have the same frame of reference as each "tile," and that never changes, so I handle it there.

Quote
Do you actually have one widget anchored to another? Because this is not shown here.

I double and quintuple checked: "horizontal" and "vertical" do indeed have anchor targets, and they are indeed precisely the same as a tile's.

Quote
Furthermore I am not sure what this "Tile" is, or what values you get from doing your math there.

The game uses a 6x6 grid of tiles to make the board. The intent of the feature is that "horizontal" and "vertical" highlight rows and columns of tiles by overlaying themselves on top of them. This is to indicate the tile on which the player is about to place a piece.

For the "vertical" piece, for example, if we're trying to highlight a tile in the 4th column out of 6 (index 3), we would get:
- Left anchor relative = 0.5 (center)
- Right anchor relative = 0.666666666667

This would position the asset at 1/6th the board width, starting 1/2 way across, to highlight the 4th row.
I have double and quintuple checked that the numbers I get on the anchors (in real-time) are consistent with themselves, the tiles' anchors, and my own math

Quote
Why are you doing any of this in the code anyway? Why can't you set it up in inspector?

I'm doing this in code because it changes in real-time. It's an input-feedback feature, highlighting one of the 36 tiles while the player's finger is over it, changing while they move.

Funny you should ask though: When I play around with these values on these assets in the inspector without the game running, I get the same behavior. If I set the left and right anchors of "vertical" both to 0.5 (center), the asset stays an absolute width. I can't make it shrink smaller than it "wants to," even in the inspector.

I've attached an image showing what I'm talking about.
  • "vertical" is anchored to boardTilesContainer, which occupies all of the empty space in the center of the screen. You can see that "vertical" should be flush with the top and bottom, and isn't.
  • You can see that "vertical" should have 0 width, and yet it doesn't.
  • Aspect Ratio is set to "free," and isn't conforming to the dimensions I'm setting. Never seen anything like this before.


ArenMook

  • Administrator
  • Hero Member
  • *****
  • Thank You
  • -Given: 337
  • -Receive: 1171
  • Posts: 22,128
  • Toronto, Canada
    • View Profile
Re: Having weird problems setting anchors in code. Is this a bug??
« Reply #6 on: April 30, 2014, 06:21:50 PM »
So that would be why. 2x2 is the smallest size a sprite can be. In case of sliced sprites, the minimum is the sum of the borders. If a sprite has a 6 pixel border on top and bottom, the minimum size is 12 pixels, like in your case vertically.

Keep in mind, NGUI is a UI system. 2x2 is in pixels. In your case your pixels are HUGE. This is not what the anchoring system is designed for, and neither was NGUI for that matter. At the very least, consider multiplying your dimensions by 10.