Unity エディタ UI 強化 Odin Inspector の Button アトリビュート详解

Odin Inspector の Button 機能概要

Odin Inspector プラグインは、Unity のデフォルト Inspector ウィンドウを大幅に拡張する強力なツールです。本記事では、特にユーザー操作に応じてメソッドを実行するために使用される「Button」関連のアトリビュート機能について、具体的なコード例と共に解説します。

1. 基本的なボタンの実装

メソッド上に [Button] アトリビュートを付与することで、Inspector にクリック可能なボタンが生成されます。クリックのたびに定義されたロジックが実行されます。このアトリビュートは多数のパラメータをサポートしており、UI デザインや表示方法を細かく制御可能です。

  • ラベル名: メソッド名またはカスタム文字列を指定可能
  • サイズ設定: Small, Medium, Large などのプリセット値、あるいはピクセル単位の数値指定
  • アイコン・スタイル: システムアイコンの使用や、背景色(GUIColor)による強調表示
  • 条件付き表示: 他のプロパティの状態(ShowIf/DisableIf など)に基づいてボタンの表示可否を切り替え

以下は、動的なラベルやカスタムスタイリングを含むボタンの実装例です。

using UnityEngine;
using Sirenix.OdinInspector;

public class InspectorButtonDemo : MonoBehaviour
{
    // ボタンのテキストを動的に生成するためのフィールド
    public string executionMessage = "Status Active";
    
    [Button("@\"Execute: \" + executionMessage)]
    private void DynamicLabelButton()
    {
        Debug.LogWarning(executionMessage + " triggered!");
    }

    [Button("標準サイズ動作")]
    private void StandardAction()
    {
        // メインロジックの実行
    }

    [Button(ButtonSizes.Medium)]
    private void MediumSizeAction()
    {
        // 中サイズのボタン動作
    }

    [Button(Icon = SdfIconType.FolderOpen), GUIColor(0.8f, 0.2f, 1f)]
    private void IconStyledButton()
    {
        // イコングレーン付きのボタン
    }
}

2. パラメータを持つメソッドとレイアウト

通常、ボタンは引数を受け取らないことが想定されていますが、Odin Inspector を使用すれば引数ありのメソッドも実行可能です。その際、パラメータの入力を展開して表示するか、あるいは折りたたみ形式にするかを指定できます。

  • FoldoutButton: パラメータ入力をカプセル化し、必要時のみ展開表示
  • Box / CompactBox: パネル状のボックスとして入力欄を描画
  • Expanded 属性: フォールドアウトを展開した状態で開始する場合の設定
using System.Collections.Generic;
using Sirenix.OdinInspector;
using UnityEngine;

public class ParameterButtonSample : MonoBehaviour
{
    // リスト保持用
    private List<int> bufferList = new List<int>();

    // デフォルトでの引数受け取り
    [Button]
    private void AppendItem(int id, float value)
    {
        bufferList.Add(id);
    }

    // フォールドアウト展開スタイルで引数を提示
    [Button(ButtonStyle.FoldoutButton)]
    private int CalculateSum(int a, int b, ref int result)
    {
        result = a + b;
        return result;
    }

    // ボックスレイアウトで複数パラメータを受け取る
    [Button(ButtonStyle.Box)]
    private void ProcessData(float x, float y, out float z)
    {
        z = x * y;
    }

    // 展開済みで表示(初期状態から入力可能)
    [Button(ButtonStyle.CompactBox, Expanded = true)]
    private void ImmediateInput(string configKey, GameObject target) 
    {
        // 即座に開く入力フォーム
    }
}

3. グループ化されたボタンの運用

複数のボタンを並べる際、[ButtonGroup] アトリビュートを使用すると視覚的なまとまりを持たせることができます。同じグループ名を指定すると横並びになり、カスタム名称を設定することも可能です。

using Sirenix.OdinInspector;
using UnityEngine;

[Serializable]
public struct ActionButtons
{
    [ButtonGroup("CommonActions")]
    [Button(SdfIconType.Play)]
    private void PlaySimulation() { }

    [ButtonGroup("CommonActions")]
    [Button(SdfIconType.Pause)]
    private void PauseSimulation() { }

    [ButtonGroup("CommonActions")]
    [Button(SdfIconType.Stop)]
    private void StopSimulation() { }

    [ButtonGroup("Special", ButtonHeight = 30)]
    [Button(SdfIconType.GearFill)]
    private void OpenSettings() { }
}

public class GroupedButtonExample : MonoBehaviour
{
    [Header("基本アクション")]
    [ButtonGroup]
    private void Submit() { }

    [ButtonGroup]
    private void Save() { }

    [ButtonGroup]
    private void Cancel() { }

    // 名前付きグループ
    [ButtonGroup("Utility Panel")]
    [GUIColor(0.2f, 0.9f, 0.2f)]
    private void InitializeSystem() { }
}

また、TitleGroupBoxGroup と組み合わせることで、階層的な UI インターフェースを作成することができます。

4. 列挙型(Enum)の操作支援

単純な Enum プロパティに対し、特定の操作を追加することが可能です。

4.1 EnumPaging

現在選択中の Enum 値に対して、「次へ」「前へ」ボタンを表示し、サイクル参照できるようにします。これはエディタツールモードの切り替えなどで有用です。

using Sirenix.OdinInspector;
using UnityEditor;

public class EnumCycleDemo : MonoBehaviour
{
    [EnumPaging]
    public SceneToolMode CurrentMode;

    public enum SceneToolMode
    {
        Move, Rotate, Scale
    }

#if UNITY_EDITOR
    [EnumPaging]
    [OnValueChanged("SwitchTool")]
    public Tool activeEditorTool;

    private void SwitchTool()
    {
        Tools.current = activeEditorTool;
    }
#endif
}

4.2 EnumToggleButtons

ドロップダウンリストではなく、水平方向のチェックボックス風ボタンとして Enum を描画します。Bitmask 型の場合はマルチセレクトとして動作します。

using Sirenix.OdinInspector;
using UnityEngine;

public class ToggleButtonEnumDemo : MonoBehaviour
{
    // 通常 Enum のハイライト表示
    [EnumToggleButtons]
    public DirectionSelection Direction;

    // ビットマス ク(複合フラグ)
    [EnumToggleButtons, HideLabel]
    public Permissions AccessLevel;

    // アイコン付き Enum 表示
    [EnumToggleButtons, HideLabel]
    public AlignmentStyle VisualAlignment;

    public enum DirectionSelection
    {
        North, East, South, West
    }

    [System.Flags]
    public enum Permissions
    {
        Read  = 1,
        Write = 2,
        Execute = 4
    }

    public enum AlignmentStyle
    {
        [LabelText(SdfIconType.AlignLeft)] Left,
        [LabelText(SdfIconType.AlignCenter)] Center,
        [LabelText(SdfIconType.AlignRight)] Right
    }
}

5. インラインボタンとリスポンシブレイアウト

[InlineButton] を使うと、プロパティの右端に小さくボタンを表示できます。
また、[ResponsiveButtonGroup] を使用すると、ウィンドウ幅の変化に応じてボタンの配置を自動調整するグリッド構成が可能になります。

using Sirenix.OdinInspector;
using UnityEngine;

public class MixedLayoutDemo : MonoBehaviour
{
    // プロパティ隣接ボタン
    [InlineButton("ResetValue"), Tooltip("現在の値をリセット")]
    public float currentFloat = 10.0f;

    [InlineButton("Save", "保存")]
    public string fileName;

    private void ResetValue() => currentFloat = 0.0f;
    private void Save() => Debug.Log($"Saving file: {fileName}");

    // スペース確保のためのダミーメソッド
    [OnInspectorGUI]
    private void Spacer() { }

    [ResponsiveButtonGroup("AutoLayout")]
    public void ActionA() { }

    [ResponsiveButtonGroup("AutoLayout")]
    public void ActionB() { }

    [ResponsiveButtonGroup("AutoLayout")]
    public void ActionC() { }

    // 同じ名前のグループ内では均等広がり
    [ResponsiveButtonGroup("EvenGrid")]
    public void Item_1() { }

    [ResponsiveButtonGroup("EvenGrid")]
    public void Item_Long_Name_Here() { }
}

これらの機能は、複雑なエディタツールのプロトタイプ作成において、迅速かつ効果的なユーザーインターフェースを実現するための基礎となります。

タグ: Odin Inspector Unity Editor C# UI Design Procedural Generation

6月14日 19:28 投稿