Unity
Unity拡張

中央ぞろえは何度も調節?まだそんなことやっているんですか? UnityEditor拡張 その1

UnityEditorの拡張を始めました。

しかし、UnityEditor拡張とかを行っていくのに、どうしてもネックになってくるのが、
UIの配置。
このボタンの配置は、真ん中に置きたいのにーーー
真ん中は配置したがいいが、特定の大きさでしか、真ん中の配置にならないよーーー

対象人物像
・エディター拡張に興味がある人
・UIの配置までこだわりたい人

開発環境
Unity2017.1.1f1
VisualStudio2017community

こんな事ってありませんか?

  • 横並びに配置したい

 例えば、UIを横並びに配置したいのに、普通に記述してしまうと縦に並んでしまいます。
 これを防ぐために以下のようなコードを記述します

sample1.cs
EditorGUILayout.BeginHorizontal();

並べたいUI

EditorGUILayout.EndHorizontal();

このEditorGUILayout.BeginHorizontalは、ここから横並びでという意味で、
必ずEditorGUILayout.EndHorizontalでくくらなければいけません。

なので、これらを使う場合は、可読性を上げるために、私の場合は、以下のように{}でくくったりします。

sample1arrange.cs
EditorGUILayout.BeginHorizontal();
{
    並べたいUI
}
EditorGUILayout.EndHorizontal();

  • 縦並びに配置したい

縦に並ぶのだから、問題ないのでは?と思った人もいるかもしれません。
しかし、横並びの途中で、縦並びの配置を使いたいそんな時ありませんか?
そういった時に、使用したりするものです。

sample2.cs
EditorGUILayout.BeginVertical();
{
    並べたいUI
}
EditorGUILayout.EndVertical();

  • 複雑なUI構成を実現したい。

縦部分で少しお話しましたが、二つを使ったものです。

sample3.cs
EditorGUILayout.BeginHorizontal();
{
    ボタンのUI
  
  EditorGUILayout.BeginVertical();
  {
    ボタンのUI
    ボタンのUI
  }
    EditorGUILayout.EndVertical();
}
EditorGUILayout.EndHorizontal();

とすると以下のような感じの並びになります。qitasample.png

  • 左寄せ(もしくは、中央寄せ、もしくは右寄せにしたい)

左寄せの場合

sample4.cs
//以下のくくりは、調整したい方向に対してのくくり
//今回は水平方向での左寄せの場合
 EditorGUILayout.BeginHorizontal();
{
    配置したいUI
    GUILayout.FlexibleSpace();
}
EditorGUILayout.EndHorizontal();

中央寄せの場合

sample5.cs
 EditorGUILayout.BeginHorizontal();
{
     GUILayout.FlexibleSpace();
    配置したいUI
    GUILayout.FlexibleSpace();
}
EditorGUILayout.EndHorizontal();

右寄せの場合

sample6.cs
 EditorGUILayout.BeginHorizontal();
{
    配置したいUI
    GUILayout.FlexibleSpace();
}
EditorGUILayout.EndHorizontal();

注意

基本的には、その前後関係に配置したいUIをおけばいいのですが、
このGUILayout.FlecibleSpace()には、とんでもない悪魔が潜んでいたりします。
内部の動きではどういった関係で、なっているのかわからないのですが
配置したいUIの幅設定をGUILayout.Expand~~(true)に弱い側面を持っています。

例えば
以下のコードを記述した場合

sample7.cs
EditorGUILayout.BegineHorizontal();
{
テキストフィールドなど、中身がないけど幅が必要なUI
GUILayout.FlexibleSpace();
}
EditorGUILayout.EndHorizontal();

と記述した場合で
幅の設定をGUILayout.Expand~~(true)にしてしまう事で
ほとんど入力欄が見えないUIが出来上がってしまいます。

ここからは推測なのですが、(ドキュメントを詳しく読み漁りきってないともいう)
基本的なUIの大きさの設定は、GUILayout.Expand~~(true)の設定で入っていて、
これはあくまでも幅が余っていたら、それに合わせて、UIを大きくする。といったもので
全ての配置が済んだ後にその大きさなどが決まる。
そしてその幅を決める処理も順序が存在しており
GUILayout.Expand~~(true)よりも先に、GUILayout.FixibleSpace()
が適用され、結果的に、後者がほとんどの幅を占有して、前者が、その残りという計算方法の結果になるからではないかと推測しています。(真実は不明)

なので、色々入れ子にした際はその辺を注意した上で、UIを構成してください。