using UnityEngine; using UnityEngine.UI; [ExecuteAlways] public class CustomWrapGrid : LayoutGroup { public float spacingX = 0f; public float spacingY = 0f; private float _containerWidth; private Vector2 _currentPos; // 新增变量记录总高度 private float _totalHeight; protected override void OnEnable() { base.OnEnable(); CalculateLayout(); } public override void SetLayoutHorizontal() { CalculateLayout(); } public override void SetLayoutVertical() { // 这里需要空实现,因为布局逻辑在SetLayoutHorizontal中完成 } public override void CalculateLayoutInputVertical() { CalculateLayout(); float minHeight = _totalHeight; SetLayoutInputForAxis(minHeight, minHeight, 0, 1); // 修正参数设置 } void CalculateLayout() { _totalHeight = 0f; // 重置总高度 if (rectChildren.Count == 0) return; _containerWidth = rectTransform.rect.width - padding.horizontal; _currentPos = new Vector2(padding.left, -padding.top); float rowHeight = 0f; foreach (RectTransform child in rectChildren) { // 跳过隐藏的对象 if (!child.gameObject.activeSelf) continue; // 获取子物体尺寸 float childWidth = LayoutUtility.GetPreferredWidth(child); float childHeight = LayoutUtility.GetPreferredHeight(child); // 换行判断 if (_currentPos.x + childWidth > _containerWidth - padding.right) { StartNewRow(ref _currentPos, ref rowHeight); } // 设置子物体位置 SetChildAlongAxis(child, 0, _currentPos.x, childWidth); SetChildAlongAxis(child, 1, _currentPos.y, childHeight); // 更新当前行状态 _currentPos.x += childWidth + spacingX; rowHeight = Mathf.Max(rowHeight, childHeight); } // 最终加上最后一行高度 _totalHeight = Mathf.Abs(_currentPos.y) + rowHeight - padding.top; } void StartNewRow(ref Vector2 pos, ref float rowHeight) { pos.x = padding.left; pos.y += rowHeight + spacingY; rowHeight = 0f; } // 当子物体变化时自动刷新 protected override void OnRectTransformDimensionsChange() { base.OnRectTransformDimensionsChange(); CalculateLayout(); } #if UNITY_EDITOR protected override void OnValidate() { base.OnValidate(); CalculateLayout(); } #endif }