using System.Collections; using System.Collections.Generic; using System.Linq; using UnityEngine; using static EZXR.Glass.UI.HorizontalLayoutGroup; namespace EZXR.Glass.UI { [ExecuteInEditMode] public class GridLayoutGroup : LayoutGroup { public List children = new List(); float prevChildCount; Vector3 prevSize; [Tooltip("单位是m")] public float horizontalSpace = 0.001f; float prevHorizontalSpace; [Tooltip("单位是m")] public float verticalSpace = 0.001f; float prevVerticalSpace; Vector3 anchor; public enum HoriAlignment { Left, Middle, Right } public HoriAlignment horiAlignment; HoriAlignment prevHoriAlignment; public enum VertAlignment { Top, Middle, Bottom } public VertAlignment vertAlignment; VertAlignment prevVertAlignment; public override void OnValidate() { if (!Application.isPlaying) { base.OnValidate(); GetSpatialUIElement(); if (horizontalSpace != prevHorizontalSpace || verticalSpace != prevVerticalSpace || spatialUIElement.size != prevSize || children.Count != prevChildCount) { prevHorizontalSpace = horizontalSpace; prevVerticalSpace = verticalSpace; prevSize = spatialUIElement.size; prevChildCount = children.Count; needReLayout = true; } } } public void AddChild(SpatialUIElement child) { if (!children.Contains(child)) { children.Add(child); needReLayout = true; } } // Update is called once per frame void Update() { if (startLayout) { if (needReLayout) { needReLayout = false; if (transform.childCount > 0) { children = new List(); for (int i = 0; i < transform.childCount; i++) { SpatialUIElement temp = transform.GetChild(i).GetComponent(); if (temp != null && temp.gameObject.activeInHierarchy) { children.Add(temp); } } int numPerRow = Mathf.FloorToInt((spatialUIElement.size.x + horizontalSpace) / (children[0].size.x + horizontalSpace)); int numPerCol = Mathf.FloorToInt((spatialUIElement.size.y + verticalSpace) / (children[0].size.y + verticalSpace)); float horiOffset = 0.0f; float vertOffset = 0.0f; switch (horiAlignment) { case HoriAlignment.Left: horiOffset = 0; break; case HoriAlignment.Middle: horiOffset = (spatialUIElement.size.x - (children[0].size.x * numPerRow + horizontalSpace * (numPerRow - 1))) / 2.0f; break; case HoriAlignment.Right: horiOffset = 0; break; } switch (vertAlignment) { case VertAlignment.Top: vertOffset = 0.0f; break; case VertAlignment.Middle: vertOffset = (spatialUIElement.size.y - (children[0].size.y * numPerCol + verticalSpace * (numPerCol - 1))) / 2.0f; break; case VertAlignment.Bottom: break; } anchor = spatialUIElement.size / 2.0f - new Vector3(horiOffset, vertOffset, 0); Vector3 curPos = Vector3.zero; for (int i = 0; i < children.Count; i++) { if (children[i] != null) { //下面的0.0000001f是为了解决float判定相等的bug if ((curPos.x + children[i].size.x <= spatialUIElement.size.x + 0.0000001f) && (curPos.y + children[i].size.y <= spatialUIElement.size.y + 0.0000001f)) { children[i].transform.localPosition = new Vector3(anchor.x - curPos.x - children[i].size.x / 2.0f, anchor.y - curPos.y - children[i].size.y / 2.0f, 0); curPos = new Vector3(curPos.x + children[i].size.x + horizontalSpace, curPos.y, curPos.z); } else if (curPos.x + children[i].size.x > spatialUIElement.size.x && curPos.y + 2.0 * children[i].size.y + verticalSpace <= spatialUIElement.size.y + 0.0000001f) { children[i].transform.localPosition = new Vector3(anchor.x - children[i].size.x / 2.0f, anchor.y - (curPos.y + children[i - 1].size.y + verticalSpace) - children[i].size.y / 2.0f, 0); curPos = new Vector3(0 + children[i].size.x + horizontalSpace, curPos.y + children[i - 1].size.y + verticalSpace, curPos.z); } else { Debug.LogError($"GridLayoutGroup: No enough space for {children[i].name}"); } } } } } } } } }