うにてぃブログ

UnityやUnreal Engineの記事を書いていきます

【Unity】UI を親にフィットさせる

RectTransform で サイズを変えた際に子供のサイズも同じように変えたい場合
Stretch に変えるだけでは下図のように子供のサイズが想定しないようになります

f:id:hacchi_man:20200411005525p:plain:w500
左:もともと 右:サイズを10倍してスケールを1/10にしたもの

これを解決するには Anchors を調整しLeft、Right、Top、Bottomを0にする必要があります

f:id:hacchi_man:20200411010255p:plain:w400

こうすることで、サイズを変えても子供のサイズも正しく変わるようになります

f:id:hacchi_man:20200411010420p:plain:w400

しかし、これを手動でやるのは面倒なので自動でやってくれるコンテキストを作成

f:id:hacchi_man:20200411011320p:plain:w400

実行すると Anchors をいい感じに調整してくれます

f:id:hacchi_man:20200411011335p:plain:w400

public static class RectTransformContext
{
    [MenuItem("CONTEXT/RectTransform/Fit Parent Rect")]
    private static void FitParentRect(MenuCommand command)
    {
        var rectTransform = (RectTransform)command.context;
        if (rectTransform.rect.width <= 0f || rectTransform.rect.height <= 0f)
            return;
 
        var parent = rectTransform.parent as RectTransform;
        if (parent == null)
            return;
         
        // Pivotを真ん中に
        if (rectTransform.pivot != Vector2.one / 2f)
            rectTransform.pivot = Vector2.one / 2f;
 
        // 親のどの位置にいるかを判定
        var halfSize = new Vector2(rectTransform.rect.width, rectTransform.rect.height) / 2F;
        var parentHalfSize = new Vector2(parent.rect.width, parent.rect.height) / 2f;
 
        rectTransform.anchorMin = InverseLerpNoClamp(parentHalfSize, rectTransform.anchoredPosition - halfSize);
        rectTransform.anchorMax = InverseLerpNoClamp(parentHalfSize, rectTransform.anchoredPosition + halfSize);
        
        // Stretch
        rectTransform.anchoredPosition = Vector2.zero;
        rectTransform.sizeDelta = Vector2.zero;
    }
 
    private static Vector2 InverseLerpNoClamp(Vector2 value, Vector2 current)
    {
        var begin = -value;
        return (current - begin) / (value - begin);
    }
}