Author Topic: Different anchoring when loading prefab dynamically or not  (Read 19363 times)

Cabal

  • Newbie
  • *
  • Thank You
  • -Given: 0
  • -Receive: 1
  • Posts: 16
    • View Profile
Different anchoring when loading prefab dynamically or not
« on: December 11, 2013, 04:52:14 PM »
Hi,

I just upgraded from 3.0.6 to 3.0.7 and converted a screen from the old anchoring to the new anchoring system.
I am however running into issues where a UIPanel prefab I create works fine if it starts in the UICamera but will be a different size (smaller) if I load it dynamically.

I have a UIPanel that contains a bunch of widgets to represent my game HUD.
The widgets are essentially set to anchor to the corners of the screen (unified anchor to the UIPanel)
The UIPanel is saved as a prefab which I am loading at runtime as follows:

   HUDPrefab = (GameObject)Resources.Load("UI/Prefabs/HUD Panel", typeof(GameObject));
   CurrentScreen = NGUITools.AddChild(MainCamera.gameObject, HUDPrefab);

The hierarchy of the prefab is as follows
UIPanel
   UIWidget (container, anchored to top left)
   UIWidget (container, anchored to top right)
   UISprite (anchored to bottom left)

When I add the prefab manually to the UICamera, it covers the entire screen as I expect (in my scenario 1777 x 768)
When I load the prefab with the code above, it ends up much smaller (1437 x 621)

I am unclear why that is happening.
The UIPanel doesn't inherently have a size, I would expect it to try and fit the camera/UIRoot regardless of how it gets loaded.

I have tried a component with the old legacy anchor on it and it ends up where I expect it to (using the full size of the screen).

Am I missing something with how the anchoring is supposed to work?

UncleAcid

  • Jr. Member
  • **
  • Thank You
  • -Given: 0
  • -Receive: 0
  • Posts: 51
    • View Profile
Re: Different anchoring when loading prefab dynamically or not
« Reply #1 on: December 11, 2013, 04:59:16 PM »
Sounds like we have more or less the same issue (I just posted about mine a little while ago as well http://www.tasharen.com/forum/index.php?topic=7100.0). You seem to have explained it better than I though.

Cabal

  • Newbie
  • *
  • Thank You
  • -Given: 0
  • -Receive: 1
  • Posts: 16
    • View Profile
Re: Different anchoring when loading prefab dynamically or not
« Reply #2 on: December 11, 2013, 06:23:54 PM »
The two do sound very similar.

Right now, it looks like for some reason the GetPixelSizeAdjustment doesn't get applied to the anchors when the prefab is loaded dynamically (as opposed to when it's placed directly in the scene)

My screen is 1437 x 621
My root is set to height 768
GetPixelSizeAdjustment is 768 x 621
My screen size x GetPixelSizeAdjustment is 1777 x 768

For some reason, the prefab that gets loaded is using the size of the screen directly and not the modified once, hence why it looks smaller.
Not sure yet where in the code that branches and if it's an issue or something I am doing wrong, but I'll keep looking.

ArenMook

  • Administrator
  • Hero Member
  • *****
  • Thank You
  • -Given: 337
  • -Receive: 1171
  • Posts: 22,128
  • Toronto, Canada
    • View Profile
Re: Different anchoring when loading prefab dynamically or not
« Reply #3 on: December 12, 2013, 12:48:02 AM »
Curious. Might be related to the way things get activated. "mRoot" is probably not set at the time. Can either of you create a simple repro case problem the example and send it to support at tasharen.com?

Cabal

  • Newbie
  • *
  • Thank You
  • -Given: 0
  • -Receive: 1
  • Posts: 16
    • View Profile
Re: Different anchoring when loading prefab dynamically or not
« Reply #4 on: December 12, 2013, 08:03:46 AM »
That is exactly what is happening. I traced it down yesterday night to the fact that mRoot is not set when the anchors are resolved.
I was able to get the anchoring to work correctly by replacing mRoot with the Find call that was there in the previous version, to find the root at the time we calculate the view size.
I will try to make a simple test case to send.

Cabal

  • Newbie
  • *
  • Thank You
  • -Given: 0
  • -Receive: 1
  • Posts: 16
    • View Profile
Re: Different anchoring when loading prefab dynamically or not
« Reply #5 on: December 12, 2013, 08:23:16 AM »
Here is a quick project showing the issue.
The scene "Prefab in the scene" shows the behavior of both legacy and new anchors when the prefab is already in the scene.
The scene "Prefab loaded" shows the behavior when the prefab is loaded dynamically.

Make sure you set your editor/game window to a smaller height than 768 (which is what the UIRoot is set to) to see the problem.
As mentioned in the previous replies, the issue I believe is that mRoot is null when the new anchoring is resolved and GetViewSize returns the size of the editor window without applying the GetPixelSizeAdjustment.

Hope this helps.
« Last Edit: December 12, 2013, 11:00:11 AM by ArenMook »

ArenMook

  • Administrator
  • Hero Member
  • *****
  • Thank You
  • -Given: 337
  • -Receive: 1171
  • Posts: 22,128
  • Toronto, Canada
    • View Profile
Re: Different anchoring when loading prefab dynamically or not
« Reply #6 on: December 12, 2013, 11:00:42 AM »
I asked to email the repro case, not post NGUI's copyrighted source code on a public forum!

Furthermore, this issue should already be addressed in 3.0.7 f2 that's out now.

UncleAcid

  • Jr. Member
  • **
  • Thank You
  • -Given: 0
  • -Receive: 0
  • Posts: 51
    • View Profile
Re: Different anchoring when loading prefab dynamically or not
« Reply #7 on: December 12, 2013, 12:10:30 PM »
The problem is now fixed, however a new issue has been introduced:

I use TweenPositions to slide UIPanels on and off screen (this also happens if I use a GameObject container and tween that instead), last version this worked fine, now it seems like my UIPanels are locked in place (the local position is right, but it doesn't move and I can see if jiggling as it fights the move). I also do not see the size gizmos on the UIPanels anymore, unless clipping is on.

If I turn on Clipping it works fine again, however the clipping has to be set manually and doesn't match the game size.

ArenMook

  • Administrator
  • Hero Member
  • *****
  • Thank You
  • -Given: 337
  • -Receive: 1171
  • Posts: 22,128
  • Toronto, Canada
    • View Profile
Re: Different anchoring when loading prefab dynamically or not
« Reply #8 on: December 12, 2013, 01:37:55 PM »
Everything seems to work fine in the Example 3 - Menu, and it also uses separate panels for each window. What's different from your setup?

UncleAcid

  • Jr. Member
  • **
  • Thank You
  • -Given: 0
  • -Receive: 0
  • Posts: 51
    • View Profile
Re: Different anchoring when loading prefab dynamically or not
« Reply #9 on: December 12, 2013, 02:08:28 PM »
Everything.

I'm using a 2D UI, I'm using TweenPosition to move stuff (the example uses animations), I'm using anchors on sprites that anchor to my panels (the example doesn't use anchors anywhere).

My hierarchy:

UIRoot
-UICamera
--GameObject - TweenPosition - to slide old level off screen and bring in new one (the child UIPanel is on the container for my levels)
---UIPanel (no clipping or anchor usage)
----Several Sprites (anchored to parent panel)
--UIPanel (no clipping or anchor usage) - TweenPosition - to slide character on and off screen
---Character Sprite (anchored to parent panel)
--UIPanel (no clipping or anchor usage) - TweenPosition - to slide some controls on and off screen
---Several Sprites (anchored to parent panel)

This worked perfectly fine in f1, so some change you made (i'm assuming in UIPanel since you fixed the scaling issue) in f2 caused this.

This is easily reproducible:
1. Create new scene
2. Create 2D UI
3. Add a GameObject as a child of Camera
4. Attach a UIPanel to the GameObject from 3
5. Add a Sprite as a child of the GameObject from 3
6. Anchor the Sprite to the UIPanel attached in 4
7. Try and move the UIPanel GameObject around, the Sprite will not move even though its parent's transform has moved
8. Change the clipping on the UIPanel to anything and now the sprite will move with it
« Last Edit: December 12, 2013, 02:22:30 PM by UncleAcid »

ArenMook

  • Administrator
  • Hero Member
  • *****
  • Thank You
  • -Given: 337
  • -Receive: 1171
  • Posts: 22,128
  • Toronto, Canada
    • View Profile
Re: Different anchoring when loading prefab dynamically or not
« Reply #10 on: December 12, 2013, 02:34:56 PM »
Aha. Well in there lies the problem:
Quote
--GameObject - TweenPosition - to slide old level off screen and bring in new one (the child UIPanel is on the container for my levels)
---UIPanel (no clipping or anchor usage)
----Several Sprites (anchored to parent panel)
When the panel has no clipping, its "bounds" are that of your screen, regardless of the panel's position. So when you anchor something to a panel that has no clipping, you're not anchoring to that panel. You're anchoring to the screen.

Do this instead:

GameObject (Panel, TweenPosition)
- UIWidget (for your bounds)
-- Several sprites (anchored to the widget)

UncleAcid

  • Jr. Member
  • **
  • Thank You
  • -Given: 0
  • -Receive: 0
  • Posts: 51
    • View Profile
Re: Different anchoring when loading prefab dynamically or not
« Reply #11 on: December 12, 2013, 02:46:50 PM »
oh, ok. how come a panel with no clipping has the screens bounds and not just the screens dimensions ? using the dimensions seems to make more sense to me. Also, why did my way work on f1, did you just impose this limitation in f2 ?

I tried setting up your approach but I must have a wrong anchor setting somewhere:

GameObject - Panel (no anchors or clipping), TweenPosition
- UIWidget - How do i make it be the screen bounds without anchors ? adding an anchor stops it from moving.
-- Several sprites (anchored to the widget) - anchored the same as with my way except to the widget instead

ArenMook

  • Administrator
  • Hero Member
  • *****
  • Thank You
  • -Given: 337
  • -Receive: 1171
  • Posts: 22,128
  • Toronto, Canada
    • View Profile
Re: Different anchoring when loading prefab dynamically or not
« Reply #12 on: December 13, 2013, 05:10:14 AM »
It worked on f1 because it was bugged. :) f2 has the correct behaviour.

So what is it you're trying to do exactly? Have your full-screen anchored UI move from off-screen somewhere?

nerophon

  • Newbie
  • *
  • Thank You
  • -Given: 0
  • -Receive: 0
  • Posts: 7
    • View Profile
Re: Different anchoring when loading prefab dynamically or not
« Reply #13 on: December 13, 2013, 06:26:56 AM »
We've been wrestling with very similar issues here. The concept of the panel is just a bit confusing, at least to me. It suggests to me something physical, visual. But actually, although the panel does have physical location in the 3D / 2D space, it's "draw space" is separate from that.

I think I have a basic understanding, technically, of why this is the case.

However! Now you can change the panel to a clipping or constraining panel. And if you turn anchoring on, anchoring gets applied to the constraints / clipping, not to the physical position. This adds one layer of confusion. AND NOW on top of that we have the fact that scroll views use panels as the basis for their scrolling, so the physical position is moving but the clip area... uh... probably isn't?

And again, the technical argument is, well, how do you handle deciding how far the scroll view may scroll? You need some kind of bounds related to some kind of viewable area.

ArenMook, you have a real talent for making technically challenging things simple for users, as demonstrated by the vast majority of NGUI. Perhaps there is a simpler solution here too?

ArenMook

  • Administrator
  • Hero Member
  • *****
  • Thank You
  • -Given: 337
  • -Receive: 1171
  • Posts: 22,128
  • Toronto, Canada
    • View Profile
Re: Different anchoring when loading prefab dynamically or not
« Reply #14 on: December 13, 2013, 08:52:04 AM »
Indeed...

To be completely honest with you, I wish I could flat our kill panels and how they work right now. The system in place was not designed for what it's being used for now, which is where majority of the issues are coming from. I'm patching it left and right in order to keep backwards compatibility, but if I was to scrap it and start over, it would be handled very differently. The way it's handled in uGUI is how it should be.

If I figure out a way to do it in NGUI without completely screwing out every single project out there, I will.

In aaaaany case... @UncleAcid, you will be happy to find a new option in the next update: "Offset" on your panels under Advanced Options. Check it, and it will behave like it did in f1.