Author Topic: Position a grid top Left of a Scroll Panel resolution independent  (Read 6696 times)

maxhap

  • Newbie
  • *
  • Thank You
  • -Given: 1
  • -Receive: 0
  • Posts: 9
    • View Profile
Hi guys,

I am trying to position a scroll view with grid and sprites to always remain in the top left corner of my window panel independent of resolution.

For my example I am trying to position Sprites in a grid contained within a Scroll View. The Scroll View is anchored within a panel which is anchored to the UI Root. When running the application in different resolutions the grid is always offset centrally. If I anchor the sprites within the grid they stay in position but then they no longer move in the scroll view (expectedly). If I add the anchor script to the grid specify top left and attached the panel to the anchor grid all the sprites get off setted way out of view.

Finally if I move any of the scroll bars the grid or scroll view repositions to the desired top/left of the screen. I have thought about writing a script that changes the grids locations pragmatically but seems overkill, there must be a better way I am just missing it.

I have attached some screenshots showing all the stages and the effets

Thanks in advanced for you help :)

ArenMook

  • Administrator
  • Hero Member
  • *****
  • Thank You
  • -Given: 337
  • -Receive: 1171
  • Posts: 22,128
  • Toronto, Canada
    • View Profile
Re: Position a grid top Left of a Scroll Panel resolution independent
« Reply #1 on: January 21, 2014, 04:03:06 AM »
I may not have understood what the issue is exactly, but my guess is that you're not considering pivot points properly. Grid elements always go toward the right and down. An anchored scroll view would have its sides stretched in all directions as the target's dimensions change. It won't keep its top-left origin. Since the grid is not anchored, neither will it stay relative to the top left. End result -- what you're getting.

UIGrid is meant for very simple positioning of objects. The anchoring system can be chained where each element is relative to the previous, eliminating the need for a UIGrid and making it be truly dynamic. I'd caution over-using the anchors however... they are not very performant.

Best approach is to do your own positioning logic and not rely on UIGrid for something like this.

maxhap

  • Newbie
  • *
  • Thank You
  • -Given: 1
  • -Receive: 0
  • Posts: 9
    • View Profile
Re: Position a grid top Left of a Scroll Panel resolution independent
« Reply #2 on: January 21, 2014, 06:36:44 AM »
Hi Aren thanks so much for the the help,

So I took your advice and decided to scrap the grid and position my objects myself. After looking into the ScrollView script I notices that there is a reset clipping function that sets the ScrollViews centre point to align the content with the upper left corner.

With thin in mind I position my content reletive to the centre line of the scroll view, after all my content is in place I call the ResetClipping function to align the content with the upper left cornet, and it worked perfectly. Until I resized the window to test resizing, the content still aligns perfectly apart from now the scroll bars no longer work, they appear disabled. After some debugging I discovered after calling ResetClipping in the ScrollView script the ForceUpdate function of the ScrollBars script never fires to update themselves so I presume that the mouse events are never getting through.

After snooping around I noticed that resetClipping function can be called from the UnityEditor from the context menu on the script, so I comment out my call, run the "game" and then immediately call the function from the context menu using the mouse. The content aligns just as it did before but the scroll bars work perfectly. My final idea was "it must be when im calling it" so I move my alignment logic to within the Update function with an if statment so it only fires once (at this point all objects should be fully initialised and in the same state as when I call the ResetClipping function from the context menu) but the scroll bars still do not work. A a final not the scroll bars reshape them-self correctly so are still in connection with the scroll view.

Any ideas?? or advice on how to do this better?

Sorry for the essay :P

Alignment code

  1.     void Update()
  2.     {
  3.         if ( !_positionsSet )
  4.         {
  5.             float heightOffset = 0.0f;
  6.  
  7.             foreach ( DayOfEvents doe in Days.Values )
  8.             {
  9.                 doe.DayPrefab.GetComponent<UISprite>().width = (int) ( gameObject.GetComponent<UIPanel>().GetViewSize().x * 0.95 );
  10.  
  11.                                 Vector3 scrollViewLocaldBounds = NGUIMath.CalculateRelativeWidgetBounds( gameObject.transform ).size;
  12.                                 Vector3 headerSpriteLocalBounds = NGUIMath.CalculateRelativeWidgetBounds( doe.DayPrefab.transform ).size;
  13.                                 Vector3 timeLineSpriteLocalBounds = NGUIMath.CalculateRelativeWidgetBounds( doe.TimeLinePrefab.transform ).size;
  14.                                
  15.                 float localY = scrollViewLocaldBounds.y / 2;
  16.                                 float headerHeight = localY - heightOffset;
  17.  
  18.                 doe.DayPrefab.transform.localPosition = new Vector3( 0.0f, headerHeight, 0.0f );
  19.  
  20.                 float timelineHeight = ( localY - ( headerSpriteLocalBounds.y / 2 ) - _headerSpacing )
  21.                                        - ( timeLineSpriteLocalBounds.y / 2 ) - heightOffset;
  22.  
  23.                 doe.TimeLinePrefab.transform.localPosition = new Vector3( 0.0f, timelineHeight, 0.0f );
  24.                                                                                                                                                   ;
  25.                 doe.TimeLinePrefab.GetComponent<UISprite>().width = doe.DayPrefab.GetComponent<UISprite>().width;
  26.  
  27.                 heightOffset += headerSpriteLocalBounds.y + timeLineSpriteLocalBounds.y + _headerSpacing;
  28.             }
  29.  
  30.             _positionsSet = true;
  31.  
  32.             gameObject.GetComponent<UIScrollView>().ResetPosition();
  33.         }
  34.     }
  35.  

ArenMook

  • Administrator
  • Hero Member
  • *****
  • Thank You
  • -Given: 337
  • -Receive: 1171
  • Posts: 22,128
  • Toronto, Canada
    • View Profile
Re: Position a grid top Left of a Scroll Panel resolution independent
« Reply #3 on: January 22, 2014, 05:45:10 AM »
Essay indeed. So what's the issue exactly? Calling ResetPosition() from code doesn't reset your scroll bars? You can call UIScrollView's UpdateScrollbars(true) function if you want to update them immediately. It should work with just ResetPosition though...

maxhap

  • Newbie
  • *
  • Thank You
  • -Given: 1
  • -Receive: 0
  • Posts: 9
    • View Profile
Re: Position a grid top Left of a Scroll Panel resolution independent
« Reply #4 on: January 22, 2014, 06:09:51 AM »
The issue is that if I call ResetPosition or UpdateScrollBars on the ScrollView from a script the attached scroll bars no longer receive events and cannot be used to scroll the content

I can upload a downloadable demo project if it would help show the problem :)

sintua

  • Jr. Member
  • **
  • Thank You
  • -Given: 7
  • -Receive: 0
  • Posts: 63
    • View Profile
Re: Position a grid top Left of a Scroll Panel resolution independent
« Reply #5 on: January 22, 2014, 12:46:35 PM »
Based on your original question, I use this awkward workaround... all my grids/tables have UIWidgets (via invisible widget, then adding the uigrid/table) on them that are set to anchor to the scroll view, but are *disabled*. I enable them for a hot second when the game starts to "align" the tables/grids, then disable them again immediately. this puts the tabled in the right spot for the resolution resize. I disabled changing the window size during the game, but you could jsut as easily add a script that will check if the window size changes, enables the anchor widgets as long as it is, and disables them again once the window stops changing size.

But yeah, having pivot points for tables would be nice. There's a user's script on here somewhere that makes an attempt at it in a similar thread about tables/pivots, if the above hacky solution isn't what you want.

maxhap

  • Newbie
  • *
  • Thank You
  • -Given: 1
  • -Receive: 0
  • Posts: 9
    • View Profile
Re: Position a grid top Left of a Scroll Panel resolution independent
« Reply #6 on: January 23, 2014, 05:42:10 AM »
Thanks for your responce sintua, I will give this a go.

Even if that works it would still be interesting to know why calling ResetClipping breaks my scroll bars

ArenMook

  • Administrator
  • Hero Member
  • *****
  • Thank You
  • -Given: 337
  • -Receive: 1171
  • Posts: 22,128
  • Toronto, Canada
    • View Profile
Re: Position a grid top Left of a Scroll Panel resolution independent
« Reply #7 on: January 23, 2014, 05:51:55 AM »
The issue is that if I call ResetPosition or UpdateScrollBars on the ScrollView from a script the attached scroll bars no longer receive events and cannot be used to scroll the content

I can upload a downloadable demo project if it would help show the problem :)
Sure, you can put it on dropbox and email me the link (just don't post it here) -- support at tasharen.com

maxhap

  • Newbie
  • *
  • Thank You
  • -Given: 1
  • -Receive: 0
  • Posts: 9
    • View Profile
Re: Position a grid top Left of a Scroll Panel resolution independent
« Reply #8 on: February 26, 2014, 06:05:18 AM »
Sorry for the late response I have been caught up in other projects. I have emailed you a link to a demo project. The scroll bar problem occurs when the scrollview is within a prefab.