(:3[kanのメモ帳]

個人ゲーム開発者kan.kikuchiのメモ的技術ブログ。月木更新でUnity関連がメイン。

(:3[kanのメモ帳]



Odinで拡張されたエディタウィンドウ OdinEditorWindow【Unity】【アセット】【Odin】【エディタ拡張】


このエントリーをはてなブックマークに追加



この記事でのバージョン
Unity 2019.4.5f1
Odin 2.1.13


はじめに

色々な属性を追加して、Inspectorを使いやすくしたり、

f:id:kan_kikuchi:20171127084846j:plain


シーン内を検証し、Inspectorでの設定に問題のあるオブジェクトを見つけたりも出来るOdinですが、

f:id:kan_kikuchi:20180104073302j:plain


なんとエディタ拡張時に使うウィンドウ用クラス、

エディタウィンドウ(EditorWindow)の拡張も可能でした……!

f:id:kan_kikuchi:20200825093817j:plain


という事で今回はその方法についての記事です。

Odin - Inspector and Serializer | Utilities Tools | Unity Asset Store



OdinEditorWindow

早速ですが、Odinによって拡張されたエディタウィンドウを使うには

EditorWindowではなく、OdinEditorWindowというクラスを継承します。

とりあえずウィンドウを開くだけのコードは以下のような感じ。

using UnityEngine;
using UnityEditor;//MenuItemを使うのに必要
using Sirenix.OdinInspector.Editor;//OdinEditorWindowを使うのに必要

/// <summary>
/// OdinEditorWindowのサンプル
/// </summary>
public class OdinEditorWindowSample : OdinEditorWindow {
  
  //=================================================================================
  //初期化
  //=================================================================================
  
  //ウィンドウを開く
  [MenuItem("Tools/Odin Editor Window Sample")]
  private static void OpenWindow() {
    GetWindow<OdinEditorWindowSample>().Show();
  }
  
}
f:id:kan_kikuchi:20200824065001j:plain



変数

OdinEditorWindowはSerializeFieldを付けた(publicでも可)

シリアライズ可能な変数はなんとウィンドウにそのまま表示されます。

[SerializeField]
private string _text = "";

[SerializeField]
private List<int> _intList = new List<int>();
f:id:kan_kikuchi:20200824065831j:plain


もちろん内容の変更も可能ですし、

ウィンドウを閉じたり、エディタを再生しても値はそのまま保持されます。


属性

Odinによって追加された属性はEditorWindowでもそのまま使う事が出来ます。

[SerializeField, BoxGroup("ボックスクループ")]
private string _text1 = "", _text2 = "";

[SerializeField, BoxGroup("ボックスクループ")]
private int _int1 = 1, _int2 = 2;
  
[SerializeField, FolderPath(RequireExistingPath = true),]
private string _outputPath = "";
f:id:kan_kikuchi:20200824102117j:plain


特にメソッドを実行出来るボタンを表示するButton属性はエディタウィンドウでは重宝します。

/// <summary>
/// ログを表示するだけのメソッド
/// </summary>
[Button(ButtonSizes.Gigantic), GUIColor(0, 1, 0)]
public void ShowDebug() {
  Debug.Log("ボタンが押されました!");
}
f:id:kan_kikuchi:20200824102217j:plain



オブジェクトの内容を表示

GetTargetというメソッドをoverrideして、そこでオブジェクトを返すと

そのオブジェクトの内容をウィンドウに表示する事が出来ます。

protected override object GetTarget() {
  //選択中のオブジェクトの内容をウィンドウに表示
  return Selection.activeObject;
}
f:id:kan_kikuchi:20200824104523j:plain


このオブジェクトはシリアライズ可能である必要はなく

Unityのオブジェクトである必要もないらしいのですが、そもそも用途はいまいち分かっていません


OdinMenuEditorWindow

OdinMenuEditorWindowを使うことで、

横にツリー状のメニューの付いたウィンドウを実装する事もできます。

using UnityEngine;
using UnityEditor;//MenuItemを使うのに必要
using Sirenix.OdinInspector.Editor;//OdinMenuEditorWindowを使うのに必要

/// <summary>
/// OdinEditorWindowのサンプル
/// </summary>
public class OdinEditorWindowSample : OdinMenuEditorWindow {
  
  //=================================================================================
  //初期化
  //=================================================================================
  
  //ウィンドウを開く
  [MenuItem("Tools/Odin Editor Window Sample")]
  private static void OpenWindow() {
    GetWindow<OdinEditorWindowSample>().Show();
  }
  
  //ツリー状のメニューの表示設定
  protected override OdinMenuTree BuildMenuTree() {
    var tree = new OdinMenuTree();
    tree.Selection.SupportsMultiSelect = false;

    tree.Add("Settings", GeneralDrawerConfig.Instance);
    tree.AddAllAssetsAtPath("Odin Settings", "Assets/Plugins/Sirenix", typeof(ScriptableObject), true, true);
    
    return tree;
  }
}
f:id:kan_kikuchi:20200824104445j:plain


なお、このOdinMenuEditorWindowに関しては別記事にて詳しく紹介する予定です。