using UnityEngine; using UnityEngine.EventSystems; using UnityEngine.UI; namespace Cryville.Common.Unity.UI { /// /// A that takes the length of one axis to compute the preferred length of the other axis with respect to a aspect ratio. /// [AddComponentMenu("Layout/Aspect Ratio Layout Element")] [ExecuteAlways] public class AspectRatioLayoutElement : UIBehaviour, ILayoutElement { [SerializeField] [Tooltip("The aspect ratio. Width divided by height.")] private float m_aspectRatio = 1; /// /// The aspect ratio. Width divided by height. /// public float AspectRatio { get { return m_aspectRatio; } set { SetProperty(ref m_aspectRatio, value); } } [SerializeField] [Tooltip("Whether to compute the length of the y axis.")] private bool m_isVertical = false; /// /// Whether to compute the length of the y axis. /// public bool IsVertical { get { return m_isVertical; } set { SetProperty(ref m_isVertical, value); } } private void SetProperty(ref T prop, T value) { if (Equals(prop, value)) return; prop = value; SetDirty(); } /// public float minWidth { get { return m_isVertical ? -1 : (transform as RectTransform).rect.height * m_aspectRatio; } } /// public float preferredWidth { get { return minWidth; } } /// public float flexibleWidth { get { return -1; } } /// public float minHeight { get { return m_isVertical ? (transform as RectTransform).rect.width / m_aspectRatio : -1; } } /// public float preferredHeight { get { return minHeight; } } /// public float flexibleHeight { get { return -1; } } /// public int layoutPriority { get { return 1; } } /// public void CalculateLayoutInputHorizontal() { } /// public void CalculateLayoutInputVertical() { } protected override void OnEnable() { base.OnEnable(); SetDirty(); } protected override void OnBeforeTransformParentChanged() { base.OnBeforeTransformParentChanged(); SetDirty(); } protected override void OnTransformParentChanged() { base.OnTransformParentChanged(); SetDirty(); } protected override void OnDidApplyAnimationProperties() { base.OnDidApplyAnimationProperties(); SetDirty(); } #if UNITY_EDITOR protected override void OnValidate() { base.OnValidate(); SetDirty(); } #endif protected override void OnDisable() { SetDirty(); base.OnDisable(); } protected override void OnRectTransformDimensionsChange() { base.OnRectTransformDimensionsChange(); SetDirty(); } bool _delayedSetDirty; private void SetDirty() { if (!IsActive()) return; if (CanvasUpdateRegistry.IsRebuildingLayout()) _delayedSetDirty = true; else LayoutRebuilder.MarkLayoutForRebuild(transform as RectTransform); } void Update() { if (!_delayedSetDirty) return; _delayedSetDirty = false; LayoutRebuilder.MarkLayoutForRebuild(transform as RectTransform); } } }