I am trying to make a list of UI elements. I want there to always be 2 columns and a potentially infinite number of rows. I want each cell to expand their x size constraint to completely fill the allocated space without any empty space on the sides. How can I achieve this?
This is what I want it to look like:
This is what I get upon changing resolutions:
Hi …i have done GridLayout using this AutoExpandGridLayoutGroup…Any idea on how to know which cell is clicked?So that I can perform certain action for that button click
You can either add a button script to the cell elements OR add a custom script that implements the IPointerClickHandler interface and get the click event.
The parent will have a collection (array/list) of the cell elements and add click listeners for all of them with a specific parameter to identify each cell.
I can write some sample code if you are still confused about this.
Basically, old script involved spacing[0] (X-spacing) in the equation for vertical (Y-spacing), so this fix just reverts spacing[0] to spacing[1] in the cases where Y-expansion should occur
Padding from the bottom d the right don’t work with this script, and padding from the top and the left pushes the cells outside the boundaries. How can I fix this?
Also, is there a way to maintain an aspect ratio with the cells? For example if you have a 2:1 window with 1:1 cells in it. Is there a way to expand the cells to fit the window while maintaining it’s shape?
not to be a downer, but the script scales all my objects to 0 along the x axis. It seems to ignore its cellsize parameter, or does not apply its calculations correctly
Edit: To simply adjust width or height I created a script to attach to the gridlayoutgroup object.
It gets the needed vales, calculates either width or height for a cell and reapplies the result
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
[ExecuteInEditMode]
[RequireComponent(typeof(UnityEngine.UI.GridLayoutGroup))]
public class AdjustGridLayoutCellSize : MonoBehaviour
{
public enum ExpandSetting { X, Y,};
public ExpandSetting expandingSetting;
GridLayoutGroup gridlayout;
int maxConstraintCount = 0;
RectTransform layoutRect;
private void Awake()
{
gridlayout = GetComponent<GridLayoutGroup>();
}
// Start is called before the first frame update
void Start()
{
UpdateCellSize();
}
// Update is called once per frame
void Update()
{
}
private void OnValidate()
{
UpdateCellSize();
}
private void UpdateCellSize()
{
maxConstraintCount = gridlayout.constraintCount;
layoutRect = gridlayout.gameObject.GetComponent<RectTransform>();
if (expandingSetting == ExpandSetting.X)
{
float width = layoutRect.rect.width;
float sizePerCell = width / maxConstraintCount;
gridlayout.cellSize = new Vector2(sizePerCell, gridlayout.cellSize.y);
}
else if (expandingSetting == ExpandSetting.Y)
{
float height = layoutRect.rect.height;
float sizePerCell = height / maxConstraintCount;
gridlayout.cellSize = new Vector2(gridlayout.cellSize.x, sizePerCell);
}
}
}
i’ve added aspect ratio control to code, because when i added Aspect Ratio Control to an object inside Grid Layout Content Size Filter of that grid didn’t work as it should.
using UnityEngine;
using UnityEngine.UI;
[ExecuteInEditMode]
[RequireComponent(typeof(UnityEngine.UI.GridLayoutGroup))]
public class AdjustGridLayoutCellSize : MonoBehaviour
{
public enum ExpandSetting { X, Y };
public ExpandSetting expandingSetting;
GridLayoutGroup _gridlayout;
public bool aspectTurn;
public float aspectRatio;
private GridLayoutGroup gridlayout
{
get
{
if (!_gridlayout)
_gridlayout = GetComponent<GridLayoutGroup>();
return _gridlayout;
}
}
int maxConstraintCount = 0;
RectTransform layoutRect;
// Start is called before the first frame update
void Start()
{
UpdateCellSize();
}
private void OnValidate()
{
UpdateCellSize();
}
private void UpdateCellSize()
{
maxConstraintCount = gridlayout.constraintCount;
layoutRect = gridlayout.gameObject.GetComponent<RectTransform>();
if (expandingSetting == ExpandSetting.X)
{
float spaceForSpacing = (maxConstraintCount - 1) * gridlayout.spacing.x;
float width = layoutRect.rect.width - spaceForSpacing;
float sizePerCell = width / maxConstraintCount;
float x = sizePerCell;
float y = gridlayout.cellSize.y;
if (aspectTurn)
y = x * aspectRatio;
//gridlayout.cellSize = new Vector2(sizePerCell, gridlayout.cellSize.y);
gridlayout.cellSize = new Vector2(x, y);
}
else if (expandingSetting == ExpandSetting.Y)
{
float spaceForSpacing = (maxConstraintCount - 1) * gridlayout.spacing.y;
float height = layoutRect.rect.height - spaceForSpacing;
float sizePerCell = height / maxConstraintCount;
float x = gridlayout.cellSize.x;
float y = sizePerCell;
if (aspectTurn)
x = y * aspectRatio;
//gridlayout.cellSize = new Vector2(gridlayout.cellSize.x, sizePerCell);
gridlayout.cellSize = new Vector2(x, y);
}
}
}
There’s no need to replace GridLayoutGroup for this, that’s adding a heap more code to maintain. The solution by Mathyx92 is a better approach IMO.
Here’s an updated version that adds the following:
Works with all GridLayoutGroup’s settings (padding, spacing, constraints)
Added optional ratio mode for cells (force square or 2:1 etc)
Thank you!
I’m testing this solution with Unity 2019.4.5. It works great in Editor but once built (tried for Windows Standalone x64 and Android), it does’nt. Do you have it working in a built game?
My bad… I populate the GridLayoutGroup from script and the items were re-scaled by Unity. I had to force the scale from my script. The element are correctly adjusted.