Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice
  3. Join us on November 16th, 2023, between 1 pm and 9 pm CET for Ask the Experts Online on Discord and on Unity Discussions.
    Dismiss Notice

Resizeable Elements in GridLayoutGroup

Discussion in 'UGUI & TextMesh Pro' started by steveg2357, Feb 4, 2015.

  1. steveg2357

    steveg2357

    Joined:
    Aug 21, 2014
    Posts:
    34
    I'd like to create a 2D panel that contains a subpanel with a GridLayoutGroup in Unity 4.6 and it seems that the only current option is to specify the size of a GridLayoutGroup cell. Specifying a constant cell size causes numerous problems, such as possibly exceeding the bounds of the subpanel, resizing the grid (e.g., changing a 2x3 grid to a 3x2 grid), etc. Is there any way to create a grid that can dynamically resize the cells relative to a subpanel and not keep them a constant cell size when a panel or subpanel changes size? GridLayoutGroup.jpg
     
  2. SimonDarksideJ

    SimonDarksideJ

    Joined:
    Jul 3, 2012
    Posts:
    1,685
    There's no automatic way to dynamically resize the cells that I'm aware of.
    But you could write a script to attach to the GO the Grid layout is attached to, to keep an eye on the screen dimensions. Then if the aspect ratio flips, you can update the Grid Layout config maybe.

    Could be a call for a new UI control for the UI Extensions library https://bitbucket.org/ddreaper/unity-ui-extensions
     
  3. Pix10

    Pix10

    Joined:
    Jul 21, 2012
    Posts:
    850
    I'm not doing this now as I'm only working in one orientation, but when I first played with grid I was simply moving the contents from one grid container to another to achieve something similar, and scaling the prefab items (the contents) accordingly. Depending on how many items you have though it might not be very nice (may be slow) on device. I didn't take to it myself.
     
  4. steveg2357

    steveg2357

    Joined:
    Aug 21, 2014
    Posts:
    34
    Suppose I have a subpanel with anchors at the corners that contains a GridLayoutGroup. If the panel is resized, I'd like to see the grid be proportionally scaled so it fits in the resized panel and does not overflow the panel, change its dimensions, etc. In particular, if I target a device that's 2Wx2H and another device that's WxH, I'd expect that the subpanel and grid were twice the width and twice the height on the former device as on the later one and in the "expected" locations. The GridLayoutGroup seems useless if there's no way to accomplish this. Any examples or ideas?
     
  5. Pix10

    Pix10

    Joined:
    Jul 21, 2012
    Posts:
    850
    The simplest approach would be to set your root canvas's Canvas Scaler to Scale With Screen Size, set a Reference Resolution and set Match Width Or Height, with the slider at 0.5 (this will give the clean W/H proportional scaling).

    The GridLayoutGroup will scale as per usual, and so will the cell dimensions and their contents.

    There are so many options though, there's always a different approach which has more of what you need, but comes with it's own cons too.
     
  6. steveg2357

    steveg2357

    Joined:
    Aug 21, 2014
    Posts:
    34
    I tried that. When I add a ContentSizeFitter, the panel and the grid rescale but the panel doesn't stay attached to the anchors at the corners.Without the ContentSizeFitter the panel stays attached to the anchors at the corners but the grid can overflow the panel and change dimensions(e.g., 2x3 can become 3x2, etc.).
     
    Last edited: Feb 5, 2015
  7. Pix10

    Pix10

    Joined:
    Jul 21, 2012
    Posts:
    850
    I gotcha, you want the contents to scale with the panel, not the screen resolution. If you're just scaling proportionately, does the Rect Transform's scale not do what you want?

    Beyond that, you're pretty much back to square one. You could scale your grid contents independently, relative to the panel resize - it will give the same results as the Rect scale, but relieve you of having to stick to proportional scaling.
     
  8. steveg2357

    steveg2357

    Joined:
    Aug 21, 2014
    Posts:
    34
    If I want a 2x3 grid, the only thing I found that seems to work is to create a panel with a Vertical Layout Group, add 2 subpanels to it with Horizontal Layout Groups and then add 3 components (i.e., cells) to the subpanels. However, adding more or fewer than 3 components doesn't give me a nice even grid. It would be nice if the GridLayoutGroup provided a similar capability that displayed the grid properly. This could be accomplished by allowing the user to specify a cell size or a grid size and then handling the layout behind the scene for the user. If a grid size is specified, there need to be "rules" for what happens if there are less or more cells than specified by the grid. For example, if the cells are filled left to right and top to bottom, 5 cells in a 2x3 grid may result in the bottom right cell being empty. Adding a 7th cell could result in (1) an error (which should be catchable in a script such as by OnGridLayoutGroupSizeExceeded), (2) the new cell inserted at the end, the 1st cell dropped and all other cells shifted down 1 cell or (3) other options. This would certainly make the GridLayoutGroup more useful.
     
  9. jamesburford

    jamesburford

    Joined:
    Nov 5, 2012
    Posts:
    4
    So, it wont resize dynamically. What I did was on Start() get the width of the scrolling area (the parent) and then divide it by the number of columns I wanted then changed the fixed cell size in the Grid Layout Group.

    Here is my code:

    Code (CSharp):
    1.     public float width;
    2.  
    3.     // Use this for initialization
    4.     void Start ()
    5.     {
    6.         width = this.gameObject.GetComponent<RectTransform>().rect.width;
    7.         Vector2 newSize = new Vector2(width / 2, width / 2);
    8.         this.gameObject.GetComponent<GridLayoutGroup>().cellSize = newSize;
    9.     }
    You can also do the same for height. Or put the code in Update() if you want it to resize constantly.

    Hope this helps!
     
  10. Roixo

    Roixo

    Joined:
    Nov 30, 2017
    Posts:
    16
    You have to add the Layout Element component to every child object.
     
    EnupGames likes this.
  11. TheGri108

    TheGri108

    Joined:
    Dec 23, 2017
    Posts:
    1
    For us, we had to check and make sure all the children of the grid, had their scale to one, because the scale gets changed for some reason.
    upload_2019-12-13_0-59-9.png
    Hopefully helps somebody!
     
  12. MuzaibRanjha

    MuzaibRanjha

    Joined:
    Aug 28, 2017
    Posts:
    6
    Code (CSharp):
    1. using UnityEngine;
    2. using UnityEngine.UI;
    3.  
    4. public class FlexibleGridLayout : MonoBehaviour
    5. {
    6.     float defaultRatio16_9 = 1.777133f;
    7.     GridLayoutGroup layout;
    8.     // Start is called before the first frame update
    9.     void Start()
    10.     {
    11.         layout = GetComponent<GridLayoutGroup>();
    12.         layout.cellSize /= Camera.main.aspect/defaultRatio16_9;
    13.         layout.padding.left =(int) (layout.padding.left / (Camera.main.aspect/defaultRatio16_9));
    14.         layout.padding.right =(int) (layout.padding.left / (Camera.main.aspect/defaultRatio16_9));
    15.         layout.padding.top =(int) (layout.padding.left / (Camera.main.aspect/defaultRatio16_9));
    16.         layout.padding.bottom =(int) (layout.padding.left / (Camera.main.aspect/defaultRatio16_9));
    17.         layout.spacing /= Camera.main.aspect/defaultRatio16_9;
    18.     }
    19. }
    20.  
     
  13. MuzaibRanjha

    MuzaibRanjha

    Joined:
    Aug 28, 2017
    Posts:
    6
    upload_2020-9-11_22-21-22.png

    this will grow the layout vertically according to the number of elements it have.

    also I have fixed the number of columns so that it will always make NumberofRows(Dynamic) x 5 Grid