需求:
如果LayoutGroup的子物体太多,超出layoutGroup的范围,则对子物体进行缩小。确保子物体都在LayoutGroup的范围内
代码:
[ExecuteInEditMode]
[RequireComponent(typeof(HorizontalOrVerticalLayoutGroup))]
public class LayoutGroupChildFitter : MonoBehaviour, ILayoutController
{[Header("最小缩放尺寸,小于0的话脚本失效")]public float m_minChildSize = -1f;[Header("是否为水平布局")]public bool m_isHorizontal = true;//layoutGroup[SerializeField] HorizontalOrVerticalLayoutGroup m_layout = null;[SerializeField] RectTransform m_rectTransform;float m_curScale = 0;//子节点List<RectTransform> m_rectChildren = new List<RectTransform>();private void Start(){if (m_layout == null)m_layout = this.transform.GetComponent<HorizontalOrVerticalLayoutGroup>();if (m_rectTransform == null) m_rectTransform = this.GetComponent<RectTransform>();DoFixChildSize();}void ILayoutController.SetLayoutHorizontal(){if (m_layout == null)m_layout = this.transform.GetComponent<HorizontalOrVerticalLayoutGroup>();if (m_rectTransform == null)m_rectTransform = this.GetComponent<RectTransform>();DoFixChildSize();}void ILayoutController.SetLayoutVertical(){if (m_layout == null)m_layout = this.transform.GetComponent<HorizontalOrVerticalLayoutGroup>();if (m_rectTransform == null)m_rectTransform = this.GetComponent<RectTransform>();DoFixChildSize();}/// <summary>/// 子节点缩放/// </summary>void DoFixChildSize(){if (m_minChildSize < 0) return;GetRectChildren();float childrenSize = GetChildrenTotalSize();float contentSize = GetContentSize();float scale = contentSize / childrenSize;scale = Mathf.Clamp(scale, m_minChildSize, 1);if (m_curScale != scale){Debug.Log($"Layout Child 缩放{contentSize}/{childrenSize}=scale:{scale}");Vector3 localScale = Vector3.one * scale;SetChildrenChild(localScale);m_curScale = scale;LayoutRebuilder.ForceRebuildLayoutImmediate(m_rectTransform);}}/// <summary>/// 把所有子节点设置/// </summary>/// <param name="localScale"></param>void SetChildrenChild(Vector3 localScale){for (int i = 0; i < m_rectChildren.Count; i++){m_rectChildren[i].localScale = localScale;}}/// <summary>/// 计算容器尺寸/// </summary>/// <returns></returns>float GetContentSize(){float size = (m_isHorizontal) ? m_rectTransform.rect.width : m_rectTransform.rect.height;//边距float padding = (m_isHorizontal) ?m_layout.padding.right + m_layout.padding.left :m_layout.padding.top + m_layout.padding.bottom;//总间距float spacing = (m_rectChildren.Count - 1) * m_layout.spacing;return size - padding - spacing;}/// <summary>/// 计算子物体总尺寸/// </summary>/// <returns></returns>float GetChildrenTotalSize(){//总长度float total = 0;for (int i = 0; i < m_rectChildren.Count; i++){if (!m_rectChildren[i].gameObject.activeInHierarchy) continue; //不考虑隐藏if (m_isHorizontal) total += m_rectChildren[i].sizeDelta.x;else total += m_rectChildren[i].sizeDelta.y;}return total;}/// <summary>/// 获取子物体/// </summary>void GetRectChildren(){if (transform.childCount == m_rectChildren.Count) return;m_rectChildren.Clear();for (int i = 0; i < transform.childCount; i++){RectTransform rect = transform.GetChild(i).GetComponent<RectTransform>();if (!m_rectChildren.Contains(rect)) m_rectChildren.Add(rect);}}
}