BuildSettingsを拡張する

UnityのBuildSettingsにプロジェクト専用のオプションを追加してみます。メニューや設定用のウインドウを用意するよりも導線が綺麗になります。

CustomBuildPlayerWindowクラスの実装

拡張したBuildSettingsの実装はこちら。スクリプトをプロジェクトにいれるとBuildSettingsが上記スクリーンショットのものに入れ替わります。

using System.Linq;
using System.Reflection;
using UnityEngine;
using UnityEditor;

class CustomBuildPlayerWindow : BuildPlayerWindow
{
    System.Action m_BaseOnGUI;

    [InitializeOnLoadMethod]
    static void OnLoad()
    {
        EditorApplication.update += () =>
        {
            var buildPlayerWindow = Resources.FindObjectsOfTypeAll<BuildPlayerWindow>().FirstOrDefault();

            if (buildPlayerWindow != null && !(buildPlayerWindow is CustomBuildPlayerWindow))
            {
                var customWindow = GetWindow<CustomBuildPlayerWindow>(typeof(BuildPlayerWindow));
                buildPlayerWindow.Close();
                customWindow.Show();
            }
        };
    }

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

        if (m_BaseOnGUI == null)
        {
            var onGUIMethod = typeof(BuildPlayerWindow).GetMethod("OnGUI", BindingFlags.Instance | BindingFlags.NonPublic);
            m_BaseOnGUI = onGUIMethod.CreateDelegate(typeof(System.Action), this) as System.Action;
        }
        m_BaseOnGUI();

        GUI.enabled = true;

        GUILayout.BeginVertical(GUILayout.Width(300));
        GUILayout.Space(2);
        GUILayout.Label("Additional Options", EditorStyles.boldLabel);

        AdditionalOptionsGUI();

        GUILayout.Space(10);
        GUILayout.EndVertical();
        GUILayout.Space(10);
        GUILayout.EndHorizontal();
    }

    void AdditionalOptionsGUI()
    {
        EditorGUILayout.Toggle("Run Tests", true);
        EditorGUILayout.Toggle("Clean Build", false);
        EditorGUILayout.Toggle("Build Asset Bundles", false);
        EditorGUILayout.Toggle("Include Awesome Assets", true);

        GUILayout.FlexibleSpace();

        GUILayout.Label("Do not go gentle into that good night,\nOld age should burn and rave at close of day,\nRage, rage against the dying of the light.\n\nDylan Thomas - 1914-1953", EditorStyles.helpBox);
    }
}

実装の説明

BuildSettingsはBuildPlayerWindowに実装されているので派生クラスを作ります。

class CustomBuildPlayerWindow : BuildPlayerWindow
{
    ...
}

次に用意したウインドウを開く処理を作ります。従来通りGetWindowを使ってウインドウを開いても良いのですが、「どこから開くんだっけ・・・?」というのを避けたいのが趣旨にありますので、ここは工夫して開かれたBuildPlayerWindowをCustomBuildPlayerWindowに置き換えるようにします。

[InitializeOnLoadMethod]
static void OnLoad()
{
    EditorApplication.update += () =>
    {
        var buildPlayerWindow = Resources.FindObjectsOfTypeAll<BuildPlayerWindow>().FirstOrDefault();

        if (buildPlayerWindow != null && !(buildPlayerWindow is CustomBuildPlayerWindow))
        {
            var customWindow = GetWindow<CustomBuildPlayerWindow>(typeof(BuildPlayerWindow));
            buildPlayerWindow.Close();
            customWindow.Show();
        }
    };
}

これで見た目はBuildSettingsと変わらないCustomBuildPlayerWindowが表示されるようになりました。

あとはOnGUIを実装すれば完成です。BuildPlayerWindowのOnGUIはプライベートなのでReflectionを使って呼び出します。

System.Action m_BaseOnGUI;

void OnGUI()
{
    if (m_BaseOnGUI == null)
    {
        var onGUIMethod = typeof(BuildPlayerWindow).GetMethod("OnGUI", BindingFlags.Instance | BindingFlags.NonPublic);
        m_BaseOnGUI = onGUIMethod.CreateDelegate(typeof(System.Action), this) as System.Action;
    }
    m_BaseOnGUI();
    ...

以前紹介したBuildPlayerWindow.RegisterBuildPlayerHandlerと相性が良いです。