【Unity】【UI Toolkit】Relative PositionとAbsolute Positionについて理解する

UnityのUI ToolkitのRelative PositionとAbsolute Positionについてまとめました。

Unity 2022.2.17

はじめに

UI Toolkitの各Visual Elementには、Positionを指定することができます。
以下のようにUI BuilderのInspectorからRelativeあるいはAbsoluteを設定できます。

Relative/Absolute

この設定はUI Toolkitのレイアウトシステムを理解する上で重要な概念になっています。
本記事ではこの概念と設定方法についてまとめます。

Relative Position

UI BuilderでVisual Elementを配置すると、デフォルトでPositionがRelativeに設定されます。
Relativeに設定されたVisual Elementは、UI Toolkitのレイアウトシステムにより座標が自動計算され、一方向に整列して並んでいきます。
下図は、Flex-Glowを0にしてHeightに固定値を入れたVisual Elementを子要素として3つ追加した図です。

子要素を3つレイアウト

Positionの下部のLeft, Top, Right, Bottomに値を入力すると、上述の通り自動計算された座標からの相対座標を設定することができます。
以下は緑色のVisual ElementのLeftに30pxを設定した例です。

Left=30px

なお、この状態では左上が起点となっているため、Rightに値を入れても変化は起こりません。
これについては親のVisual ElementのFlex Directionを変えた時に変化が起こることが確認できます。

またFlex Directionの説明など、Flexboxの概念については本記事の主旨から逸れるため割愛します。

Absolute Position

PositionをAbsoluteにすると、その要素の座標は自動計算の対象から外され、入力した座標は親のVisual Elementからの相対座標となります。
たとえば緑のVisual ElementのPositionをRelativeからAbsoluteに変更すると、下図のような結果になります。

Absolute

まず、緑のVisual Elementが自動整列の対象から外れ、赤と青だけが綺麗に整列されていることがわかります。

緑の要素に関しては親からの相対座標で配置されています。
前節でLeftに30pxを入力しているため、親から30pxだけ左に配置された状態になっていることがわかります。

このように、レイアウトを自動計算させたくない場合にはPostionをAbsoluteにします。

スクリプトで指定する

上述Positionの設定をスクリプトから設定するには以下のように行います。

using UnityEditor;
using UnityEngine;
using UnityEngine.UIElements;

public sealed class Example : EditorWindow
{
    private void CreateGUI()
    {
        var root = rootVisualElement;
        var parent = new VisualElement();
        root.Add(parent);

        // 赤いVisual Element
        var red = new VisualElement();
        red.style.backgroundColor = new Color(0.75f, 0.0f, 0.0f);
        red.style.width = 100.0f;
        red.style.height = 100.0f;
        red.style.position = Position.Relative;
        parent.Add(red);

        // 緑のVisual Element
        var green = new VisualElement();
        green.style.backgroundColor = new Color(0.0f, 0.75f, 0.0f);
        green.style.width = 100.0f;
        green.style.height = 100.0f;
        green.style.position = Position.Absolute;
        green.style.left = 30.0f;
        parent.Add(green);

        // 青いVisual Element
        var blue = new VisualElement();
        blue.style.backgroundColor = new Color(0.0f, 0.0f, 0.75f);
        blue.style.width = 100.0f;
        blue.style.height = 100.0f;
        blue.style.position = Position.Relative;
        parent.Add(blue);
    }

    [MenuItem("Window/Example")]
    public static void ShowWindow()
    {
        GetWindow<Example>();
    }
}

結果は下図の通りです。

結果

スタイルシートで指定する

USSで設定する場合は以下のようにします。

#Red{
    width: 100px;
    height: 100px;
    background-color: #BF0000;
    position:relative;
}
#Green{
    width: 100px;
    height: 100px;
    background-color: #00BF00;
    position:absolute;
    left: 30px;
}
#Blue{
    width: 100px;
    height: 100px;
    background-color: #0000BF;
    position:relative;
}

参考

docs.unity3d.com

docs.unity3d.com