UnityのUGIの自動レイアウト機能に上限をつける方法

# 概要
UnityのUGIの自動レイアウト機能では、LayoutElementを使うことで下限を設定することはできますが、上限については設定することができません。
そのため、たとえば自動でサイズが変わる吹き出しのようなものを作りたいときに改行が自動でされないなどの問題が発生しました。今回は自動レイアウトされる際に任意の上限までにしたいときの解決方法を紹介します。


# やり方
こちらのフォーラムにあるRectSizeLimiterをつかうことで実現できます。ソースコードは下にも記載しています。

https://forum.unity.com/threads/rect-transform-size-limiter.620860/

こちらのスクリプトを作成後、サイズを制限したいオブジェクトにスクリプトをアタッチして、RectTransformを指定、制限したいサイズを入力することで上限を設定できます。なおこちらのスクリプトは0が指定されているときは機能しないようになっているため、下限を0にしたい場合などは別途対応が必要です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/104976/333a30d0-9045-c849-d4e8-87ba54bbcfe2.png)

## ソースコード（引用）
``` c#
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;
 
[ExecuteInEditMode]
public class RectSizeLimiter : UIBehaviour, ILayoutSelfController
{
 
    public RectTransform rectTransform;
 
    [SerializeField]
    protected Vector2 m_maxSize = Vector2.zero;
 
    [SerializeField]
    protected Vector2 m_minSize = Vector2.zero;
 
    public Vector2 maxSize
    {
        get { return m_maxSize; }
        set
        {
            if (m_maxSize != value)
            {
                m_maxSize = value;
                SetDirty();
            }
        }
    }
 
    public Vector2 minSize
    {
        get { return m_minSize; }
        set
        {
            if (m_minSize != value)
            {
                m_minSize = value;
                SetDirty();
            }
        }
    }
 
    private DrivenRectTransformTracker m_Tracker;
 
    protected override void OnEnable()
    {
        base.OnEnable();
        SetDirty();
    }
 
    protected override void OnDisable()
    {
        m_Tracker.Clear();
        LayoutRebuilder.MarkLayoutForRebuild(rectTransform);
        base.OnDisable();
    }
 
    protected void SetDirty()
    {
        if (!IsActive())
            return;
 
        LayoutRebuilder.MarkLayoutForRebuild(rectTransform);
    }
 
    public void SetLayoutHorizontal()
    {
        if (m_maxSize.x > 0f && rectTransform.rect.width > m_maxSize.x)
        {
            rectTransform.SetSizeWithCurrentAnchors(RectTransform.Axis.Horizontal, maxSize.x);
            m_Tracker.Add(this, rectTransform, DrivenTransformProperties.SizeDeltaX);
        }
 
        if (m_minSize.x > 0f && rectTransform.rect.width < m_minSize.x)
        {
            rectTransform.SetSizeWithCurrentAnchors(RectTransform.Axis.Horizontal, minSize.x);
            m_Tracker.Add(this, rectTransform, DrivenTransformProperties.SizeDeltaX);
        }
 
    }
 
    public void SetLayoutVertical()
    {
        if (m_maxSize.y > 0f && rectTransform.rect.height > m_maxSize.y)
        {
            rectTransform.SetSizeWithCurrentAnchors(RectTransform.Axis.Vertical, maxSize.y);
            m_Tracker.Add(this, rectTransform, DrivenTransformProperties.SizeDeltaY);
        }
 
        if (m_minSize.y > 0f && rectTransform.rect.height < m_minSize.y)
        {
            rectTransform.SetSizeWithCurrentAnchors(RectTransform.Axis.Vertical, minSize.y);
            m_Tracker.Add(this, rectTransform, DrivenTransformProperties.SizeDeltaY);
        }
 
    }
 
#if UNITY_EDITOR
    protected override void OnValidate() 
    {
        base.OnValidate();
        SetDirty();
    }
#endif
 
}
```