IMGUI システムを使用しているときに UI の配置と整理を行うには、固定と自動の 2 つの方法があります。本ガイドでは、すべての例において固定レイアウトを使用してきました。自動レイアウトを使用するには、コントロール関数を呼び出す際に、GUI の代わりに、GUILayout を記述します。固定レイアウトは、1 つのレイアウトモードを使用する必要はありませんが、同じ OnGUI() 関数で一度に両方のモードを使用することができます。
固定レイアウトは、事前に設計されたインターフェースで作業する場合に使用します。自動レイアウトは、前もって必要な要素の数が分からない場合、や各コントロールの配置について気にしたくない場合に使用します。例えば、Save Game ファイルに基づいて、各種ボタンを作成している場合、描画するボタンの数が分からないとします。この場合、自動レイアウトを使用する方が便利です。ゲームの設計とどのようにインターフェースを表示したいかに強く依存しています。
自動レイアウトを使用した場合、2 つの大きな差があります。
/* 自動レイアウトを使うときの 2 つの主な違い */
// JavaScript
function OnGUI () {
// 固定レイアウト
GUI.Button (Rect (25,25,100,30), "I am a Fixed Layout Button");
// 自動レイアウト
GUILayout.Button ("I am an Automatic Layout Button");
}
// C#
using UnityEngine;
using System.Collections;
public class GUITest : MonoBehaviour {
void OnGUI () {
// 固定レイアウト
GUI.Button (new Rect (25,25,100,30), "I am a Fixed Layout Button");
//自動レイアウト
GUILayout.Button ("I am an Automatic Layout Button");
}
}
使用しているレイアウトモードに応じて、コントロールを配置する場所やグループ化する方法をコントロールするための各種仕掛けがあります。固定レイアウトでは、各種コントロールを Groups に分けることができます。自動レイアウトでは、各種コントロールを Areas 、Horizontal Groups 、 Vertical Groups に分けることができます。
グループを固定レイアウトモードで利用できる手法です。これにより、複数のコントロールを含む画面のエリアを定義できます。GUI.BeginGroup() や GUI.EndGroup() 関数を使用することで、グループ内に置くコントロールを定義できます。グループ内にあるすべてのコントロールは、画面の左上ではなく、グループの左上に基づいて配置されます。このように、ランタイム時にグループを最配置する場合、グループ内のすべてのコントロールの相対位置は維持されます。
例として、画面上で複数のコントロールを中心に置くと非常に簡単です。
/* グループを使って複数のコントロールを画面の中心に置く */
// JavaScript
function OnGUI () {
// 画面の中心にグループを作ります。
GUI.BeginGroup (Rect (Screen.width / 2 - 50, Screen.height / 2 - 50, 100, 100));
// すべての四角をグループに調整します。 (0,0) はグループの左上の端です。
// ボックスを作ります。すると、画面上でどもにグループがあるかわかります。
GUI.Box (Rect (0,0,100,100), "Group is here");
GUI.Button (Rect (10,40,80,30), "Click me");
// 上で開始したグループを終了します。これは、忘れずに行わなければいけません。
GUI.EndGroup ();
}
// C#
using UnityEngine;
using System.Collections;
public class GUITest : MonoBehaviour {
void OnGUI () {
// 画面の中心にグループを作ります。
GUI.BeginGroup (new Rect (Screen.width / 2 - 50, Screen.height / 2 - 50, 100, 100));
// すべての四角をグループに調整します。 (0,0) はグループの左上の端です。
// ボックスを作ります。すると、画面上でどもにグループがあるかわかります。
GUI.Box (new Rect (0,0,100,100), "Group is here");
GUI.Button (new Rect (10,40,80,30), "Click me");
// 上で開始したグループを終了します。これは、忘れずに行わなければいけません。
GUI.EndGroup ();
}
}
それぞれの内部で複数のグループをネストすることもできます。これを行うと、各グループは、その内容をその親の空間に対して、切り取らせます。
/* 表示したコンテンツをクリップするために複数のグループを使用します*/
// JavaScript
var bgImage : Texture2D; //背景画像、 256 x 32
var fgImage : Texture2D; //前景画像、 256 x 32
var playerEnergy = 1.0; // 0.0 から 1.0 までの float
function OnGUI () {
// 両方の画像を含むグループを作成
// 最初の 2 座標を調整し、画面上のどこかに置きます
GUI.BeginGroup (Rect (0,0,256,32));
// 背景画像を描画します。
GUI.Box (Rect (0,0,256,32), bgImage);
// クリップされる2番目のグループを描画
// 画像をクリップしますが、スケールはしません。それが、2番目のグループが必要な理由です。
GUI.BeginGroup (Rect (0,0,playerEnergy * 256, 32));
// 前景画像を描画します。
GUI.Box (Rect (0,0,256,32), fgImage);
//両グループを終了します。
GUI.EndGroup ();
GUI.EndGroup ();
}
// C#
using UnityEngine;
using System.Collections;
public class GUITest : MonoBehaviour {
// 背景画像、256 x 32
public Texture2D bgImage;
// 前景画像、256 x 32
public Texture2D fgImage;
//0.0 から 1.0 までの float
public float playerEnergy = 1.0f;
void OnGUI () {
// 両方の画像を含むグループを作成
// 最初の 2 座標を調整し、画面上のどこかに置きます
GUI.BeginGroup (new Rect (0,0,256,32));
// 背景画像を描画します。
GUI.Box (new Rect (0,0,256,32), bgImage);
// クリップされる2番目のグループを描画
// 画像をクリップしますが、スケールはしません。それが、2番目のグループが必要な理由です。
GUI.BeginGroup (new Rect (0,0,playerEnergy * 256, 32));
// 前景画像を描画します。
GUI.Box (new Rect (0,0,256,32), fgImage);
// 両グループを終了します。
GUI.EndGroup ();
GUI.EndGroup ();
}
}
エリアは、自動レイアウトでのみ使用されます。GUILayout コントロールを含ませるための画面の制限された部分を定義するため、機能は固定レイアウトに似ています。自動レイアウトの性質上、ほとんど常にエリアを使用することになります。
自動レイアウトモードでは、コントロールがコントロールレベルで描画される画面のエリアを定義しません。コントロールは自動的に含んでいるエリアの左上に配置されます。これは画面の場合があります。自身で手動配置されたエリアを作成することもできます。エリア内の GUILayout コントロールは、エリアの左上に配置されます。
/* エリア内のどこにも位置しないボタンと、画面の半分の位置に位置するボタン */
// JavaScript
function OnGUI () {
GUILayout.Button ("I am not inside an Area");
GUILayout.BeginArea (Rect (Screen.width/2, Screen.height/2, 300, 300));
GUILayout.Button ("I am completely inside an Area");
GUILayout.EndArea ();
}
// C#
using UnityEngine;
using System.Collections;
public class GUITest : MonoBehaviour {
void OnGUI () {
GUILayout.Button ("I am not inside an Area");
GUILayout.BeginArea (new Rect (Screen.width/2, Screen.height/2, 300, 300));
GUILayout.Button ("I am completely inside an Area");
GUILayout.EndArea ();
}
}
エリア内で、ボタンやボックスのような表示要素は、その幅をエリアの全体の長さにまで延長します。
自動レイアウトを使用すると、コントロールはデフォルトで次々と上から下に表示されます。コントロールを配置する場所や配置方法をより繊細にコントロールする必要がある場合が多くあります。自動レイアウトモードを使用している場合、水平や垂直グループのオプションがあります。
その他のレイアウトコントロール同様、個々の関数を呼び出して、これらのグループを開始や終了できます。この関数は、GUILayout.BeginHoriztontal()、GUILayout.EndHorizontal()、GUILayout.BeginVertical() 、GUILayout.EndVertical() です。
水平グループ内のコントロールは常に水平に配置されます。垂直グループ内のコントロールは常に垂直に配置されます。これは、グループをそれぞれの内部でネスト化するまでは簡単に聞こえます。これにより、想像できる構成で、任意の数のコントロールを配置できます。
/* ネストになった水平と垂直のグループ を使用 */
// JavaScript
var sliderValue = 1.0;
var maxSliderValue = 10.0;
function OnGUI()
{
//指定した GUI Area のすべてをラップ
GUILayout.BeginArea (Rect (0,0,200,60));
// 1 つの水平グループを開始
GUILayout.BeginHorizontal();
// ボタンを通常通り配置
if (GUILayout.RepeatButton ("Increase max\nSlider Value"))
{
maxSliderValue += 3.0 * Time.deltaTime;
}
// ボタンの横に、垂直方向にコントロールをもう2 つ設定
GUILayout.BeginVertical();
GUILayout.Box("Slider Value: " + Mathf.Round(sliderValue));
sliderValue = GUILayout.HorizontalSlider (sliderValue, 0.0, maxSliderValue);
// Groups と Area を終了
GUILayout.EndVertical();
GUILayout.EndHorizontal();
GUILayout.EndArea();
}
// C#
using UnityEngine;
using System.Collections;
public class GUITest : MonoBehaviour {
private float sliderValue = 1.0f;
private float maxSliderValue = 10.0f;
void OnGUI()
{
// 指定した GUI Area のすべてをラップ
GUILayout.BeginArea (new Rect (0,0,200,60));
//1 つの水平グループを開始
GUILayout.BeginHorizontal();
//ボタンを通常通り配置
if (GUILayout.RepeatButton ("Increase max\nSlider Value"))
{
maxSliderValue += 3.0f * Time.deltaTime;
}
// ボタンの横に、垂直方向にコントロールをもう2 つ設定
GUILayout.BeginVertical();
GUILayout.Box("Slider Value: " + Mathf.Round(sliderValue));
sliderValue = GUILayout.HorizontalSlider (sliderValue, 0.0f, maxSliderValue);
// Groups と Area を終了
GUILayout.EndVertical();
GUILayout.EndHorizontal();
GUILayout.EndArea();
}
}
GUILayoutOptions を使用して、自動レイアウトパラメーターの一部を無効にできます。これは、GUILayout コントロールの最終パラメーターを渡すことで行います。
上記の例のエリアでは、ボタンはその幅をエリアの最大幅に延長します。必要な場合はこれを無効にできます。
/* GUILayoutOptions を使って自動レイアウトコントロールプロパティーをオーバーライド */
//JavaScript
function OnGUI () {
GUILayout.BeginArea (Rect (100, 50, Screen.width-200, Screen.height-100));
GUILayout.Button ("I am a regular Automatic Layout Button");
GUILayout.Button ("My width has been overridden", GUILayout.Width (95));
GUILayout.EndArea ();
}
// C#
using UnityEngine;
using System.Collections;
public class GUITest : MonoBehaviour {
void OnGUI () {
GUILayout.BeginArea (new Rect (100, 50, Screen.width-200, Screen.height-100));
GUILayout.Button ("I am a regular Automatic Layout Button");
GUILayout.Button ("My width has been overridden", GUILayout.Width (95));
GUILayout.EndArea ();
}
}
考えられる GUILayoutOption の完全なリストに関しては、GUILayoutOption を参照してください。