using Cysharp.Threading.Tasks; using UnityEngine; using UnityEngine.UI; //控制目标的最大最小尺寸 [ExecuteAlways] public class LayoutElementSizeClamp : LayoutElement { [SerializeField] bool m_ClampEnable; public bool clampEnable { get { return m_ClampEnable; } set { m_ClampEnable = value; } } [SerializeField] Clamp m_Clamp; public Clamp clamp { get { return m_Clamp; } } [SerializeField] RectTransform m_Target; protected override void OnEnable() { base.OnEnable(); if (clampEnable && m_Target != null) { UpdateRect().Forget(); } } async UniTask UpdateRect() { await UniTask.DelayFrame(1); preferredHeight = -1; preferredWidth = -1; //频繁调用ForceRebuildLayoutImmediate的原因是 // 如Text要自适应宽高又要限制宽高, 先要处理宽度刷新后才能计算换行 // 强制重新计算布局 LayoutRebuilder.ForceRebuildLayoutImmediate(transform.parent as RectTransform); preferredWidth = Mathf.Clamp(m_Target.rect.width, m_Clamp.minX, m_Clamp.maxX); // 强制重新计算布局 LayoutRebuilder.ForceRebuildLayoutImmediate(transform.parent as RectTransform); preferredHeight = Mathf.Clamp(m_Target.rect.height, m_Clamp.minY, m_Clamp.maxY); } [System.Serializable] public struct Clamp { public float minX; public float maxX; public float minY; public float maxY; } }