コガネブログ

平日更新を目標に Unity や C#、Visual Studio、ReSharper などのゲーム開発アレコレを書いていきます

【Unity】using static を使用してエディタ拡張の OnGUI の記述を少し楽にする

はじめに

この記事は「Unity #3 Advent Calendar 2019」の 12/5 の記事です

private void OnGUI()
{
    EditorGUILayout.BeginHorizontal();

    if ( GUILayout.Button( "ピカチュウ" ) )
    {
    }

    if ( GUILayout.RepeatButton( "ライチュウ" ) )
    {
    }

    EditorGUILayout.EndHorizontal();

    EditorGUILayout.BeginHorizontal();
    EditorGUILayout.PrefixLabel( "ああああ" );
    EditorGUILayout.TextField( "いいいい" );
    EditorGUILayout.EndHorizontal();
}

エディタ拡張で OnGUI を記述する時は、基本的には上記のような感じになりますが
関数呼び出しで毎回 EditorGUILayout、GUILayout と記述するのが面倒だったので、

using static EditorGUILayoutWrapper;

...

private void OnGUI()
{
    BeginHorizontal();

    if ( Button( "ピカチュウ" ) )
    {
    }

    if ( RepeatButton( "ライチュウ" ) )
    {
    }

    EndHorizontal();

    BeginHorizontal();
    PrefixLabel( "ああああ" );
    TextField( "いいいい" );
    EndHorizontal();
}

このように EditorGUILayout や GUILayout と記述する必要がなくなるスクリプトを作りました

使い方

https://gist.github.com/baba-s/263615f7d73a96bab28de14f8fa8d4bc

上記ページのスクリプトを Unity プロジェクトの「Editor」フォルダに追加して

using static EditorGUILayoutWrapper;

OnGUI 関数を記述するスクリプトの先頭に上記の using static を追加すると使用できます

説明

using static UnityEngine.Mathf;

using static を使用すると

var result = Mathf.Max( 25, 151 );

上記のような関数呼び出しで

var result = Max( 25, 151 );

クラス名を省略できるようになります

using static UnityEditor.EditorGUILayout;

そのため、EditorGUILayout などの Unity のクラスも using static することで

private void OnGUI()
{
    // 通常
    EditorGUILayout.LabelField( "ピカチュウ" );

    // using static
    LabelField( "ピカチュウ" );
}

このように EditorGUILayout を省略して記述できます

private void OnGUI()
{
    EditorGUILayout.LabelField( "ピカチュウ" );

    GUILayout.Button( "ライチュウ" );
}

そこで、自分はよくエディタ拡張で EditorGUILayout と GUILayout を使うため

using static UnityEditor.EditorGUILayout;
using static UnityEngine.GUILayout;

EditorGUILayout と GUILayout を using static してみたところ

private void OnGUI()
{
    LabelField( "ピカチュウ" );

    Button( "ライチュウ" );
}

基本的には使うことができたのですが、

private void OnGUI()
{
    BeginHorizontal(); // エラー
    EndHorizontal(); // エラー
    
    BeginScrollView(); // エラー
    EndScrollView();   // エラー
}

BeginHorizontal や BeginScrollView を使おうとした時にエラーになってしまいました

これは、BeginHorizontal や BeginScrollView が
EditorGUILayout にも GUILayout にも存在するため、
クラス名を省略するとどちらのクラスの関数を使うのか判断できなくなってしまうためです

public static class EditorGUILayoutWrapper

そこで、自分は専用のクラスを定義して

public static void LabelField( string label, params GUILayoutOption[] options )
{
    EditorGUILayout.LabelField( label, options );
}

public static bool Toggle( bool value, params GUILayoutOption[] options )
{
    return EditorGUILayout.Toggle( value, options );
}

...

EditorGUILayout のすべての関数のラッパーを作成しました

public static bool Button( Texture image, params GUILayoutOption[] options )
{
    return GUILayout.Button( image, options );
}

public static void Box( Texture image, params GUILayoutOption[] options )
{
    GUILayout.Box( image, options );
}

...

そして、EditorGUILayout に存在する関数と名前が競合していない
GUILayout のいくつかの関数のラッパーも追加しました
(BeginHorizontal などのラッパーは EditorGUILayout の物のみ定義した)

using static EditorGUILayoutWrapper;

こうして作成した専用のクラスを using static することで

private void OnGUI()
{
    BeginHorizontal();  // EditorGUILayout

    if ( Button( "ピカチュウ" ) )  // GUILayout
    {
    }

    if ( RepeatButton( "ライチュウ" ) )  // GUILayout
    {
    }

    EndHorizontal();  // EditorGUILayout

    BeginHorizontal();  // EditorGUILayout
    PrefixLabel( "ああああ" );  // EditorGUILayout
    TextField( "いいいい" );  // EditorGUILayout
    EndHorizontal();  // EditorGUILayout
}
  • EditorGUILayout のすべての関数をクラス名を省略して使用できる
  • EditorGUILayout と GUILayout で名前が競合している関数は
    EditorGUILayout が優先される

このような形になります

これで、using static を使用してエディタ拡張の OnGUI の記述が少し楽になります