Search Unity

Unity UI Move GridLayoutGroup Rectransform based on its cell into centre of GridLayoutGroup's Parent

Discussion in 'UGUI & TextMesh Pro' started by jGate99, Oct 11, 2019.

  1. jGate99

    jGate99

    Joined:
    Oct 22, 2013
    Posts:
    1,940
    Hi there,

    I have a Parent RectRansform with fixed height and width.
    And a Child GridLayoutGroup which has its own 100 cells. andthis GridLayoutGroup width and height is bigger than Parent RectTransform, so only some of those cells are visible.

    Now what i want to achieve is that i want to move GridLayoutGroup in a way so its random child is always in centre of Parent RectTransform.

    I have attached the picture so you can understand what i want to achieve.

    Please advise
    Thanks

    Capture.PNG
     
    Last edited: Oct 11, 2019
  2. Antistone

    Antistone

    Joined:
    Feb 22, 2014
    Posts:
    2,836
    You can move your grid relative to the parent by adjusting its anchoredPosition. To calculate where to move it, you'll need to know the dimensions of your grid and the coordinates of the specific cell.

    I wrote something a lot like this for controlling the map in a grid-based game I made. This is probably a little more complex than strictly necessary for your case, but I think it would serve as a reasonable example...
    Code (CSharp):
    1. // The point (in game board coordinates) in the center of the visible area in the UI
    2. public Vector2 FocalPoint
    3. {
    4.     get
    5.     {
    6.         Vector2 pt = mapRT.anchoredPosition;
    7.         pt = pt.ComponentDivide(mapRT.localScale);  // Scale based on zoom
    8.         pt = pt.Rotate(-mapRT.localEulerAngles.z);  // Rotate
    9.         pt *= -1;   // Invert (moving the map up shows us rooms with lower coordinates)
    10.         return ScreenToBoard(pt);
    11.     }
    12.     set
    13.     {
    14.         Vector2 pt = BoardToScreen(value);
    15.         pt *= -1;   // Invert (moving the map up shows us rooms with lower coordinates)
    16.         pt = pt.Rotate(mapRT.localEulerAngles.z);
    17.         pt = pt.ComponentMultiply(mapRT.localScale);
    18.         mapRT.anchoredPosition = pt;
    19.     }
    20. }
    21.  
    22. // Returns the UI coordinates corresponding to a given location on the game board
    23. public Vector2 BoardToScreen(Vector2 gameLoc)
    24. {
    25.     return new Vector2((gameLoc.x - .5f * (topRight.x + botLeft.x)) * roomSize.x,
    26.                        (gameLoc.y - .5f * (topRight.y + botLeft.y)) * roomSize.y);
    27. }
    28. // Returns a point on the game board corresponding to a given UI coordinate
    29. public Vector2 ScreenToBoard(Vector2 screenPoint)
    30. {
    31.     return new Vector2(screenPoint.x / roomSize.x + .5f * (topRight.x + botLeft.x),
    32.                        screenPoint.y / roomSize.y + .5f * (topRight.y + botLeft.y));
    33. }
    34.  
    35. // Vector2 extension methods (actually located in a different class)
    36. public static Vector2 ComponentMultiply(this Vector2 v, Vector2 other)
    37. {
    38.     return new Vector2(v.x * other.x, v.y * other.y);
    39. }
    40. public static Vector2 ComponentDivide(this Vector2 v, Vector2 other)
    41. {
    42.     return new Vector2(v.x / other.x, v.y / other.y);
    43. }
    44.  
    topRight and botLeft are the grid coordinates of the top-right and bottom-left grid cells, respectively, and roomSize is the size of one grid cell (including padding, if any). I assume that positive X is to the right, positive Y is up, and that the map's anchors are (0.5, 0,5). Notice this works even if the map (grid) has a scale or rotation that is different from its parent.
     
    jGate99 likes this.
  3. jGate99

    jGate99

    Joined:
    Oct 22, 2013
    Posts:
    1,940
    Thank you for providing code snippet and explanation otherwise i'd not be able to write on my own due to bad math skillset.
    Thanks again :)