123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149 |
- 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<SpatialUIElement> children = new List<SpatialUIElement>();
- 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<SpatialUIElement>();
- for (int i = 0; i < transform.childCount; i++)
- {
- SpatialUIElement temp = transform.GetChild(i).GetComponent<SpatialUIElement>();
- 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}");
- }
- }
- }
- }
- }
- }
- }
- }
- }
|