e.blog

主にUnity/UE周りのことについてまとめていきます

PlayerPrefsを操作するエディタウィンドウを作成する

概要

EditorWindowを継承した、エディタ拡張のメモです。
普段、エディタ作成をそんなにしていないので忘れがちなので。

ちなみに今回は、汎用的になるようにPlayerPrefsを操作するっていう名目でサンプルを作成しました。

準備

エディタ拡張の詳細はここでは触れません。
ここではEditorWindowクラスを継承して、ウィンドウタイプのエディタ拡張を制作するまでを書きます。

まず、UnityEditor.EditorWindowクラスを継承したクラスを作成します。
ウィンドウのインスタンスは初回のみ生成するようにしています。
ウィンドウの生成にはCreateInstance<T>();スタティックメソッドを利用します。

メニューから生成されるには以下のようにします。

public class PlayerPrefsEditor : EditorWindow
{
    static private PlayerPrefsEditor _window;

    [MenuItem("Window/PlayerPrefsEditor")]
    static private void Open()
    {
        if (_window == null)
        {
            _window = CreateInstance<PlayerPrefsEditor>();
        }
    }
}

メニューには以下のように表示され、これを実行するとウィンドウが開きます。

f:id:edo_m18:20180520110044p:plain

ウィンドウの描画処理

ウィンドウが生成されると、インスペクタのエディタ拡張などと同じくOnGUIメソッドが定期的に呼ばれるようになります。
そこに、ボタンやラベルなどを表示させ、インタラクションさせることによってエディタを実装します。

private void OnGUI()
{
    EditorGUILayout.LabelField("---- PlayerPrefs List ----");
}

この中に様々な処理を書けばリッチなエディタを作ることができます。
今回は実際に使用した部分だけをメモとして残しておきます。

スクロールビューを作る

項目が増えてくるとスクロールしないと収まらなくなってきます。
そんなときはスクロールビューを実装します。

スクロールビューにしたい箇所をGUILayout.BeginScrollView()GUILayout.EndScrollView()ではさみます。

具体的には以下のようにします。

private Vector2 _scrollPos;

private void OnGUI()
{
    _scrollPos = GUILayout.BeginScrollView(_scrollPos, GUI.skin.box);

    // ... do anything.

    GUILayout.EndScrollView();
}

_scrollPosは現在のスクロール状態を保持するためにインスタンス変数として保持しておきます。

項目を枠でグルーピングする

また、項目が増えてくると各項目ごとにグルーピングしたくなってきます。
その場合はスクロールビューと似た感じでEditorGUILayout.BeginVertical()EditorGUILayout.EndVertical()のメソッドで項目をはさみます。

private void OnGUI()
{
    EditorGUILayout.BeginVertical(GUI.skin.box, GUILayout.ExpandWidth(true));

    // ... do anything.

    EditorGUILayout.EndVertical();
}

最後に、最近のプロジェクトで使ったやつを一部を伏せつつ載せておきます。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
using ElminaAR.Systems;

public class PlayerPrefsEditor : EditorWindow
{
    static private PlayerPrefsEditor _window;
    static private readonly string _userDataFoldoutKey = "UserDataFoldoutKey";

    private Vector2 _scrollPos;

    private bool _isFirst;

    [MenuItem("Window/PlayerPrefsEditor")]
    static private void Open()
    {
        if (_window == null)
        {
            _window = CreateInstance<PlayerPrefsEditor>();
        }

       #region ### Player Config ###
        _window._isFirst = PlayerConfig.IsFirstPlay;
       #endregion ### Player Config ###

        _window.ShowUtility();
    }

    private void OnGUI()
    {
        ShowEdit();
    }

    private void OnDestroy()
    {
        //
    }

    /// <summary>
    /// エディット画面を表示する
    /// </summary>
    private void ShowEdit()
    {
        _scrollPos = GUILayout.BeginScrollView(_scrollPos, GUI.skin.box);
        EditorGUILayout.LabelField("---- Player Config ----");
        _isFirst = EditorGUILayout.Toggle("初回プレイ: ", _isFirst);
        GUILayout.EndScrollView();

        if (GUILayout.Button("更新"))
        {
            Apply();
        }
    }

    /// <summary>
    /// PlayerPrefsを更新
    /// </summary>
    private void Apply()
    {
        PlayerConfig.IsFirstPlay = _isFirst;
    }
}

これを実際に表示すると以下のようなウィンドウになります。(一部マスク)

f:id:edo_m18:20180612095428p:plain