using System; using System.Collections; using System.Collections.Generic; using UnityEngine; namespace BF { [ExecuteInEditMode] public class BFHorizontalOrVerticalLayout : BFLayoutBase { [SerializeField] protected float spacing = 0; public float Spaceing { get { return spacing; } set { SetProperty(ref spacing, value); } } [SerializeField] protected bool verticalOrHorizontal = true; public bool VerticalOrHorizontal { get { return verticalOrHorizontal; } set { SetProperty(ref verticalOrHorizontal, value); } } private float verticalSize = 0f; private float horizontalSize = 0f; public void Update() { if (!isDirty) { return; } RefreshLayout(); } public void RefreshLayout() { CalculateLayoutInput(); if (verticalOrHorizontal) { CalChildPosVertical(); } else { CalChildPosHorizontal(); } isDirty = false; } protected void CalculateLayoutInput() { RectChildren.Clear(); var toIgnoreList = new List(); for (var i = 0; i < RectTransform.childCount; i++) { var rect = (RectTransform)RectTransform.GetChild(i); if (rect != null && rect.gameObject.activeSelf) { RectChildren.Add(rect); } } toIgnoreList = null; } protected void CalChildPosVertical() { verticalSize = 0f; var rectSizeX = RectTransform.sizeDelta.x; var rectSizeY = RectTransform.sizeDelta.y; var tmpVec2 = Vector2.zero; for (var i = 0; i < RectChildren.Count; ++i) { tmpVec2 = RectChildren[i].sizeDelta * RectChildren[i].localScale; verticalSize += tmpVec2.y + Spaceing; horizontalSize = Mathf.Max(horizontalSize, tmpVec2.x); } verticalSize -= Spaceing; //align参数 var horizontalAlign = (int)ChildAlignment % 3; var verticalAlign = (int)ChildAlignment / 3; var horMiddlePos = 0f; horMiddlePos += (rectSizeX - Right - Left) / 2 + Left; //垂直开始位置 var verStartPos = 0f; if (verticalAlign == 0) //upper { verStartPos += Top; } else if (verticalAlign == 1) //middle { if (verticalSize + Top + Bottom > rectSizeY) { verStartPos += Top; } else { verStartPos += (rectSizeY - verticalSize) / 2; } } else if (verticalAlign == 2) //lower { if (verticalSize + Top + Bottom > rectSizeY) { verStartPos += Top; } else { verStartPos += rectSizeY - verticalSize - Bottom; } } for (var i = 0; i < RectChildren.Count; ++i) { //设置水平位置 var rect = RectChildren[i]; if (horizontalAlign == 0) //left { SetChildAlongAxis(rect, 0, Left); } else if (horizontalAlign == 1) //center { SetChildAlongAxis(rect, 0, horMiddlePos - rect.sizeDelta.x * rect.localScale.x / 2); } else if (horizontalAlign == 2) //right { SetChildAlongAxis(rect, 0, rectSizeX - Right - rect.sizeDelta.x * rect.localScale.x); } //设置垂直位置 SetChildAlongAxis(rect, 1, verStartPos); verStartPos += rect.sizeDelta.y * rect.localScale.y + spacing; } } protected void CalChildPosHorizontal() { horizontalSize = 0f; var rectSizeX = RectTransform.sizeDelta.x; var rectSizeY = RectTransform.sizeDelta.y; var tmpVec2 = Vector2.zero; for (var i = 0; i < RectChildren.Count; ++i) { tmpVec2 = RectChildren[i].sizeDelta * RectChildren[i].localScale; horizontalSize += tmpVec2.x + Spaceing; verticalSize = Mathf.Max(verticalSize, tmpVec2.y); } horizontalSize -= Spaceing; //align参数 var horizontalAlign = (int)ChildAlignment % 3; var verticalAlign = (int)ChildAlignment / 3; var verMiddlePos = 0f; verMiddlePos += (rectSizeY - Top - Bottom) / 2 + Top; //水平开始位置 var horStartPos = 0f; if (horizontalAlign == 0) //left { horStartPos += Left; } else if (horizontalAlign == 1) //middle { if (horizontalSize + Left + Right > rectSizeX) { horStartPos += Left; } else { horStartPos += (rectSizeX - horizontalSize) / 2; } } else if (horizontalAlign == 2) //right { if (horStartPos + Left + Right > rectSizeX) { horStartPos += Left; } else { horStartPos += rectSizeX - horizontalSize - Right; } } for (var i = 0; i < RectChildren.Count; ++i) { //设置垂直位置 var rect = RectChildren[i]; if (verticalAlign == 0) //upper { SetChildAlongAxis(rect, 1, Top); } else if (verticalAlign == 1) //center { SetChildAlongAxis(rect, 1, verMiddlePos - rect.sizeDelta.y * rect.localScale.y / 2, rect.sizeDelta.y); } else if (verticalAlign == 2) //lower { SetChildAlongAxis(rect, 1, rectSizeY - Bottom - rect.sizeDelta.y * rect.localScale.y, rect.sizeDelta.y); } //设置水平位置 SetChildAlongAxis(rect, 0, horStartPos); horStartPos += rect.sizeDelta.x * rect.localScale.x + spacing; } } public float GetVerticalSize() { return verticalSize + Top + Bottom; } public float GetHorizontalSize() { return horizontalSize + Left + Right; } } }