【Unity】LayoutGroupは高さのみ変更とか面倒なので自作してみた

Unity

Unity初心者です。

現在2Dでゲームを作成しているのですが、綺麗にレイアウトを並べたい時には「LayoutGroup」を多用してきました。(HorizontalLayoutGroupとか)

なんか調べるとUnityのLayoutGroupは評判が良くないみたいでしたが、お手軽ですごい便利に使っていました。座標指定よりレスポンシブに作ることが出来ますし。

しかし、HorizontalLayoutGroupを使用して横(PosX)は調整したいが、高さ(PosY)は自分で決めたいみたいな時があって対応に苦労しました。

というのもHorizontalLayoutGroupを使っているとPosYは自動で決められてしまうからです。

↑Upper、Middle、Lowerから選ぶしかない

とりあえず面倒だったので、自作でレイアウトを揃えられるようにしました。作ったソースなどを記載してみたいと思います。

自作のLayoutGroupで実現したい動作

↑オブジェクトの水平位置を3分割しつつ、高さは不揃えにする

前述したとおりHorizontalLayoutGroupを使うと水平方向に均等に配置することは出来るのですが、高さが勝手に決まるので上記要件を実現できませんでした。

ちなみにLayoutGroupにはGridLayoutGroupというものがあります。

GridLayoutGroupに空のゲームオブジェクトを間に挟んでいけば実現できそうでしたが、流石に保守性が悪くなりそうなので辞めました。

自作のLayoutGroupのソースコード

「自作!!」とかカッコイイことは言いましたが、単純に親要素の大きさを分割して並べているだけの、しょぼいコードです。

using UnityEngine;

public class NewBehaviourScript : MonoBehaviour
{
    private float width;
    private float height;
    private int childCount;
    void Start()
    {
        // 親オブジェクトの高さと幅を取得
        RectTransform rect = GetComponent<RectTransform> ();
        width  = rect.sizeDelta.x;
        height = rect.sizeDelta.y;
        childCount = 0;
    }

    void Update()
    {
        // 要素数が変更になったら並びを整える
        if(childCount != this.transform.childCount)
        {
            SetLayout();
        }
        childCount = this.transform.childCount;
    }

    private void SetLayout()
    {
        for (int i = 0; i < this.transform.childCount; i++){
            // 子オブジェクトを均等間隔に並べる
            Transform child = this.transform.GetChild(i);
            float left = width * (i + 1) / (this.transform.childCount+ 1) - width / 2;
            float top = height * (i + 1) / (this.transform.childCount+ 1) - height / 2;
            child.localPosition = new Vector3(left, top, 0);
        }
    }
}

最初に親要素の横幅と縦幅を取得します。

上記で取得した値を子の数で割った値を算出し、positionを変更してあげているだけです。

一応自動で変更されるようにしたかったのでUpdateで呼び出しをする形にしました。

Updateで毎回計算するのもどうかと思ったので、子要素の数に変更がなければ何もしないようにしています。

後は必要になるとしたら

  • Spanを指定できるようにする
  • オプションで左側から並べられるようにする(Alignment Left)

くらいですかねー。

LayoutGroupを複数使用すれば調整可能

そもそも何故自作で作ることにしたかを書いておこうと思います。

元々は自作するつもりがなくて、LayoutGroupを使用したまま要件を満たせないかを考えてきました。

結論から言うと同じような悩みを持っている人がいて、やり方が公開されていました。

(teratailの質問です)

Unity の HorizontalLayoutGroup を使うと Pos Y がいじれなくなるのを回避したい。

https://teratail.com/questions/194411

こちらのやり方を真似しようと思ったのですが、「間にもう1階層増やす」という方法が取られていて、LayoutGroupを重ねる方法が紹介されていました。

正直LayoutGroupを階層にしていくのは構造上よろしくないような気がしたので、今回自作をしてみました。

ただ、見ていくと「HorizontalLayoutGroup」を継承して「SetLayoutVertical」メソッドを空でオーバーライドしてあげるという方法も記載されていました。

こちらを使用する方法も良い気がしますね。

(階層表示の回答を見て閉じてしまったので、見つけるのが遅かった…)

コメント

タイトルとURLをコピーしました