EditorWindow
クラスに以下のメソッドがあったため、これを利用すればモーダルウィンドウとして表示できると思い利用してみたところ、TreeView が想定と異なる挙動をしたためその解決方法を記述します
/// <summary> /// <para>Show the EditorWindow as a floating modal window.</para> /// </summary> public void ShowModalUtility() { this.ShowWithMode(ShowMode.ModalUtility); this.MakeModal(); }
モーダルウィンドとは以下のものを示します
モーダルウィンドウは、元のウィンドウの上に別枠で表示されるウィンドウのことです。 指定された操作を完了、もしくはキャンセルするまでずっと表示され続け、他のウィンドウに移ることができません。
おかしな挙動
以下の通り、Expand や Collapse した際の反映がが遅れてしまっています
検証に用いたスクリプトは記事の最後に添付しておきます
原因
公式リファレンスを見てみたところ、以下のように記述されていました
Note: You do not need to use EditorWindow.GetWindow before using this function to show the window.
つまり、ShowModalUtility
を呼び出す際には GetWindow
を利用しないということです
実際に記述したスクリプトを見てみると、GetWindow
を呼び出してからの ShowModalUtility
を行っています
private static void Show() { var window = GetWindow<ModalWindow>(); window.ShowModalUtility(); }
これを、公式リファレンスを元に書き換えるとこうなります
private static void Show() { var window = CreateInstance(typeof(ModalWindow)) as ModalWindow; window.ShowUtility(); }
確認
先程の修正を行い、モーダルウィンドウを表示させてみると想定通りの挙動となりました
スクリプト
using UnityEditor; using UnityEditor.IMGUI.Controls; using UnityEngine; public class ModalWindow : EditorWindow { [MenuItem("Tools/ModalSample")] private static void Show() { var window = GetWindow<ModalWindow>(); window.ShowModalUtility(); } [SerializeField] private TreeViewState _state; private SampleTreeView _treeView; private void Init() { if (_state == null) _state = new TreeViewState(); if (_treeView == null) _treeView = new SampleTreeView(_state); } private void OnGUI() { Init(); var rect = GUILayoutUtility.GetRect(0, 0, position.width, position.height); _treeView.OnGUI(rect); } } public class SampleTreeView : TreeView { public SampleTreeView(TreeViewState state) : base(state) { Reload(); } protected override TreeViewItem BuildRoot() { var root = new TreeViewItem(0, -1, "Root"); for (var i = 1; i < 5; i++) { var item = new TreeViewItem(i, 0, i.ToString()); for (var j = 1; j < 5; j++) { var child = new TreeViewItem(i * 5 + j, 1, i + "_" + j); item.AddChild(child); } root.AddChild(item); } SetupDepthsFromParentsAndChildren(root); return root; } }