UI update 02

This commit is contained in:
FloatGaming
2026-06-30 21:21:30 +08:00
parent b2a1e307a4
commit f62f643cfc
1666 changed files with 211081 additions and 22799 deletions
+234
View File
@@ -0,0 +1,234 @@
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
[AddComponentMenu("Layout/Flow Layout Group")]
public class FlowLayoutGroup : LayoutGroup
{
[SerializeField] private float spacingX = 10f;
[SerializeField] private float spacingY = 10f;
[SerializeField] private bool expandChildHeight = false;
[SerializeField] private float forcedChildHeight = 120f;
private readonly List<RowInfo> rows = new List<RowInfo>();
private float calculatedPreferredHeight;
private struct RowInfo
{
public int startIndex;
public int endIndex;
public float width;
public float height;
}
public float SpacingX
{
get => spacingX;
set => SetProperty(ref spacingX, value);
}
public float SpacingY
{
get => spacingY;
set => SetProperty(ref spacingY, value);
}
public bool ExpandChildHeight
{
get => expandChildHeight;
set => SetProperty(ref expandChildHeight, value);
}
public float ForcedChildHeight
{
get => forcedChildHeight;
set => SetProperty(ref forcedChildHeight, value);
}
public override void CalculateLayoutInputHorizontal()
{
base.CalculateLayoutInputHorizontal();
CalculateRows();
float minWidth = padding.horizontal;
float preferredWidth = rectTransform.rect.width > 0f ? rectTransform.rect.width : minWidth;
SetLayoutInputForAxis(minWidth, preferredWidth, -1f, 0);
}
public override void CalculateLayoutInputVertical()
{
CalculateRows();
SetLayoutInputForAxis(calculatedPreferredHeight, calculatedPreferredHeight, -1f, 1);
}
public override void SetLayoutHorizontal()
{
CalculateRows();
SetChildrenAlongAxis();
}
public override void SetLayoutVertical()
{
CalculateRows();
SetChildrenAlongAxis();
}
private void CalculateRows()
{
rows.Clear();
float availableWidth = GetAvailableWidth();
float currentRowWidth = 0f;
float currentRowHeight = 0f;
int currentRowStart = 0;
bool hasRow = false;
for (int i = 0; i < rectChildren.Count; i++)
{
RectTransform child = rectChildren[i];
if (child == null) continue;
float childWidth = Mathf.Max(LayoutUtility.GetPreferredSize(child, 0), LayoutUtility.GetMinSize(child, 0), child.rect.width);
float childHeight = expandChildHeight
? forcedChildHeight
: Mathf.Max(LayoutUtility.GetPreferredSize(child, 1), LayoutUtility.GetMinSize(child, 1), child.rect.height);
float requiredWidth = hasRow ? currentRowWidth + spacingX + childWidth : childWidth;
bool shouldWrap = hasRow && requiredWidth > availableWidth;
if (shouldWrap)
{
rows.Add(new RowInfo
{
startIndex = currentRowStart,
endIndex = i - 1,
width = currentRowWidth,
height = currentRowHeight
});
currentRowStart = i;
currentRowWidth = childWidth;
currentRowHeight = childHeight;
}
else
{
currentRowWidth = hasRow ? requiredWidth : childWidth;
currentRowHeight = Mathf.Max(currentRowHeight, childHeight);
hasRow = true;
}
}
if (hasRow)
{
rows.Add(new RowInfo
{
startIndex = currentRowStart,
endIndex = rectChildren.Count - 1,
width = currentRowWidth,
height = currentRowHeight
});
}
calculatedPreferredHeight = padding.vertical;
for (int i = 0; i < rows.Count; i++)
{
calculatedPreferredHeight += rows[i].height;
if (i < rows.Count - 1)
{
calculatedPreferredHeight += spacingY;
}
}
}
private void SetChildrenAlongAxis()
{
float availableWidth = GetAvailableWidth();
float y = padding.top;
for (int rowIndex = 0; rowIndex < rows.Count; rowIndex++)
{
RowInfo row = rows[rowIndex];
float startX = GetRowStartX(availableWidth, row.width);
float x = startX;
for (int i = row.startIndex; i <= row.endIndex; i++)
{
RectTransform child = rectChildren[i];
if (child == null) continue;
float childWidth = Mathf.Max(LayoutUtility.GetPreferredSize(child, 0), LayoutUtility.GetMinSize(child, 0), child.rect.width);
float childHeight = expandChildHeight
? forcedChildHeight
: Mathf.Max(LayoutUtility.GetPreferredSize(child, 1), LayoutUtility.GetMinSize(child, 1), child.rect.height);
float offsetY = GetChildVerticalOffset(row.height, childHeight);
SetChildAlongAxis(child, 0, x, childWidth);
SetChildAlongAxis(child, 1, y + offsetY, childHeight);
x += childWidth + spacingX;
}
y += row.height + spacingY;
}
}
private float GetRowStartX(float availableWidth, float rowWidth)
{
TextAnchor anchor = childAlignment;
switch (anchor)
{
case TextAnchor.UpperCenter:
case TextAnchor.MiddleCenter:
case TextAnchor.LowerCenter:
return padding.left + Mathf.Max(0f, (availableWidth - rowWidth) * 0.5f);
case TextAnchor.UpperRight:
case TextAnchor.MiddleRight:
case TextAnchor.LowerRight:
return padding.left + Mathf.Max(0f, availableWidth - rowWidth);
default:
return padding.left;
}
}
private float GetChildVerticalOffset(float rowHeight, float childHeight)
{
TextAnchor anchor = childAlignment;
switch (anchor)
{
case TextAnchor.MiddleLeft:
case TextAnchor.MiddleCenter:
case TextAnchor.MiddleRight:
return Mathf.Max(0f, (rowHeight - childHeight) * 0.5f);
case TextAnchor.LowerLeft:
case TextAnchor.LowerCenter:
case TextAnchor.LowerRight:
return Mathf.Max(0f, rowHeight - childHeight);
default:
return 0f;
}
}
private float GetAvailableWidth()
{
float availableWidth = rectTransform.rect.width - padding.horizontal;
if (availableWidth > 0f)
{
return availableWidth;
}
RectTransform parentRect = rectTransform.parent as RectTransform;
if (parentRect != null)
{
availableWidth = parentRect.rect.width - padding.horizontal;
if (availableWidth > 0f)
{
return availableWidth;
}
}
return float.PositiveInfinity;
}
}