GridLayoutGroup默认的居中效果:
不是真正的居中 加上代码:
namespace UnityEngine.UI
{/// <summary>/// GridLayoutGroup拓展,使支持自定义内容/// </summary>internal class GridLayoutGroupEx : GridLayoutGroup{/// <summary>/// 启用居中/// </summary>bool m_enableMiddle = true;/// <summary>/// 超过行数采用默认的/// </summary>int m_surpassLine = 2;public bool EnableMiddle{set { m_enableMiddle = value; }get { return m_enableMiddle; }}public int SurpassLine{set { m_surpassLine = value; }get { return m_surpassLine; }}/// <summary>/// Called by the layout system/// Also see ILayoutElement/// </summary>public override void SetLayoutHorizontal(){SetCellsAlongAxis(0);}/// <summary>/// Called by the layout system/// Also see ILayoutElement/// </summary>public override void SetLayoutVertical(){SetCellsAlongAxis(1);}private void SetCellsAlongAxis(int axis){// Normally a Layout Controller should only set horizontal values when invoked for the horizontal axis// and only vertical values when invoked for the vertical axis.// However, in this case we set both the horizontal and vertical position when invoked for the vertical axis.// Since we only set the horizontal position and not the size, it shouldn't affect children's layout,// and thus shouldn't break the rule that all horizontal layout must be calculated before all vertical layout.if (axis == 0){// Only set the sizes when invoked for horizontal axis, not the positions.for (int i = 0; i < rectChildren.Count; i++){RectTransform rect = rectChildren[i];m_Tracker.Add(this, rect,DrivenTransformProperties.Anchors |DrivenTransformProperties.AnchoredPosition |DrivenTransformProperties.SizeDelta);rect.anchorMin = Vector2.up;rect.anchorMax = Vector2.up;rect.sizeDelta = cellSize;}return;}float width = rectTransform.rect.size.x;float height = rectTransform.rect.size.y;int cellCountX = 1;int cellCountY = 1;if (m_Constraint == Constraint.FixedColumnCount){cellCountX = m_ConstraintCount;if (rectChildren.Count > cellCountX)cellCountY = rectChildren.Count / cellCountX + (rectChildren.Count % cellCountX > 0 ? 1 : 0);}else if (m_Constraint == Constraint.FixedRowCount){cellCountY = m_ConstraintCount;if (rectChildren.Count > cellCountY)cellCountX = rectChildren.Count / cellCountY + (rectChildren.Count % cellCountY > 0 ? 1 : 0);}else{if (cellSize.x + spacing.x <= 0)cellCountX = int.MaxValue;elsecellCountX = Mathf.Max(1, Mathf.FloorToInt((width - padding.horizontal + spacing.x + 0.001f) / (cellSize.x + spacing.x)));if (cellSize.y + spacing.y <= 0)cellCountY = int.MaxValue;elsecellCountY = Mathf.Max(1, Mathf.FloorToInt((height - padding.vertical + spacing.y + 0.001f) / (cellSize.y + spacing.y)));}int cornerX = (int)startCorner % 2;int cornerY = (int)startCorner / 2;int cellsPerMainAxis, actualCellCountX, actualCellCountY;if (startAxis == Axis.Horizontal){cellsPerMainAxis = cellCountX;actualCellCountX = Mathf.Clamp(cellCountX, 1, rectChildren.Count);actualCellCountY = Mathf.Clamp(cellCountY, 1, Mathf.CeilToInt(rectChildren.Count / (float)cellsPerMainAxis));}else{cellsPerMainAxis = cellCountY;actualCellCountY = Mathf.Clamp(cellCountY, 1, rectChildren.Count);actualCellCountX = Mathf.Clamp(cellCountX, 1, Mathf.CeilToInt(rectChildren.Count / (float)cellsPerMainAxis));}Vector2 requiredSpace = new Vector2(actualCellCountX * cellSize.x + (actualCellCountX - 1) * spacing.x,actualCellCountY * cellSize.y + (actualCellCountY - 1) * spacing.y);Vector2 startOffset = new Vector2(GetStartOffset(0, requiredSpace.x),GetStartOffset(1, requiredSpace.y));int customActualCellCountX, customActualCellCountY;if (startAxis == Axis.Horizontal){customActualCellCountX = rectChildren.Count % cellCountX;customActualCellCountY = Mathf.Clamp(cellCountY, 1, Mathf.CeilToInt(rectChildren.Count / (float)cellsPerMainAxis));}else{customActualCellCountY = rectChildren.Count % cellCountY;customActualCellCountX = Mathf.Clamp(cellCountX, 1, Mathf.CeilToInt(rectChildren.Count / (float)cellsPerMainAxis));}Vector2 customRequiredSpace = new Vector2(customActualCellCountX * cellSize.x + (customActualCellCountX - 1) * spacing.x,customActualCellCountY * cellSize.y + (customActualCellCountY - 1) * spacing.y);Vector2 customStartOffset = new Vector2(GetStartOffset(0, customRequiredSpace.x),GetStartOffset(1, customRequiredSpace.y));//Debug.Log("actualCellCountX: " + actualCellCountX);//Debug.Log("actualCellCountY: " + actualCellCountY);//Debug.Log("requiredSpace.x: " + requiredSpace.x);//Debug.Log("requiredSpace.y: " + requiredSpace.y);//Debug.Log("startOffset.x: " + startOffset.x);//Debug.Log("startOffset.y: " + startOffset.y);//Debug.Log("-------------------------------");//Debug.Log("customActualCellCountX: " + customActualCellCountX);//Debug.Log("customActualCellCountY: " + customActualCellCountY);//Debug.Log("customRequiredSpace.x: " + customRequiredSpace.x);//Debug.Log("customRequiredSpace.y: " + customRequiredSpace.y);//Debug.Log("customStartOffset.x: " + customStartOffset.x);//Debug.Log("customStartOffset.y: " + customStartOffset.y);int startCount = rectChildren.Count % cellsPerMainAxis;int totalLine = startAxis == Axis.Horizontal ? customActualCellCountY : customActualCellCountX;for (int i = 0; i < rectChildren.Count; i++){int positionX;int positionY;if (m_enableMiddle && startCount > 0 && totalLine <= m_surpassLine){if (i < startCount){if (startAxis == Axis.Horizontal){positionX = i;positionY = 0;if (cornerX == 1)positionX = startCount - 1 - positionX;if (cornerY == 1)positionY = actualCellCountY - 1 - positionY;}else{positionX = 0;positionY = i;if (cornerX == 1)positionX = actualCellCountX - 1 - positionX;if (cornerY == 1)positionY = startCount - 1 - positionY;}SetChildAlongAxis(rectChildren[i], 0, customStartOffset.x + (cellSize[0] + spacing[0]) * positionX, cellSize[0]);SetChildAlongAxis(rectChildren[i], 1, customStartOffset.y + (cellSize[1] + spacing[1]) * positionY, cellSize[1]);}else{int index = i - startCount;if (startAxis == Axis.Horizontal){positionX = index % cellsPerMainAxis;positionY = index / cellsPerMainAxis + 1;}else{positionX = index / cellsPerMainAxis + 1;positionY = index % cellsPerMainAxis;}if (cornerX == 1)positionX = actualCellCountX - 1 - positionX;if (cornerY == 1)positionY = actualCellCountY - 1 - positionY;SetChildAlongAxis(rectChildren[i], 0, startOffset.x + (cellSize[0] + spacing[0]) * positionX, cellSize[0]);SetChildAlongAxis(rectChildren[i], 1, startOffset.y + (cellSize[1] + spacing[1]) * positionY, cellSize[1]);}}else{if (startAxis == Axis.Horizontal){positionX = i % cellsPerMainAxis;positionY = i / cellsPerMainAxis;}else{positionX = i / cellsPerMainAxis;positionY = i % cellsPerMainAxis;}if (cornerX == 1)positionX = actualCellCountX - 1 - positionX;if (cornerY == 1)positionY = actualCellCountY - 1 - positionY;SetChildAlongAxis(rectChildren[i], 0, startOffset.x + (cellSize[0] + spacing[0]) * positionX, cellSize[0]);SetChildAlongAxis(rectChildren[i], 1, startOffset.y + (cellSize[1] + spacing[1]) * positionY, cellSize[1]);}//Debuger.Log("positionX: " + positionX + "positionY: " + positionY + ",cellsPerMainAxis: " + cellsPerMainAxis);}}}
}
效果: