【Unity2019.1a11】InspectorでもUIElementsを使う

Cluster,Inc. Advent Calendar 2018、10日目の記事です。

qiita.com

概要

Unity2019にて、UIElementsUnityEngine.Experimental.UIElementsからUnityEngine.UIElementsへ移行しました。

従来はOnGUIなどでデータが変更されるたびに再描画していましたが、UIElementsを使うことでツリー構造としてイベント駆動で扱えるようになるため、より軽く、より楽に使えるようになります

インスペクタからでも使えるようになった他、使い方も少し変わっているので紹介していきます。

エディタ拡張で使う

それぞれ、2018系から下記のように変更されています。

  • this.GetRootVisualContainer()rootVisualElement
  • UnityEngine.Experimental.UIElements.ButtonUnityEngine.UIElements.Button
using UnityEditor;
using UnityEngine;
using UnityEngine.UIElements;

public class FooEditorWindow : EditorWindow
{
    [MenuItem("Window/FooEditorWindow")]
    public static void Open()
    {
        GetWindow<FooEditorWindow>();
    }

    void OnEnable()
    {
        
        var button = new Button(() => Debug.Log("Clicked!"))
        {
            text = "Click me"
        };
        rootVisualElement.Add(button);
    }
}

従来どおりUnityEditor.Experimental.UIElementsを使おうとすると、下記のようなエラーが出るので注意してください。

InvalidOperationException: UIElements can't run in Experimental and Public mode at the same time. Please update your code to use the UnityEngine.UIElements namespace. Use SwitchUIElementMode() to change namespaces
UnityEditor.GUIView.get_panel () (at C:/buildslave/unity/build/Editor/Mono/GUIView.cs:54)
UnityEditor.GUIView.get_visualTree ()
UnityEditor.HostView.UpdatePlayModeColor (Color newColorToUse) (at C:/buildslave/unity/build/Editor/Mono/HostView.cs:669)
UnityEditor.HostView.PlayModeStateChangedCallback (PlayModeStateChange state) (at C:/buildslave/unity/build/Editor/Mono/HostView.cs:654)
UnityEditor.EditorApplication.Internal_PlayModeStateChanged (PlayModeStateChange state) (at C:/buildslave/unity/build/Editor/Mono/EditorApplication.cs:302)
UnityEngine.GUIUtility:ProcessEvent(Int32, IntPtr)

Window/FooEditorWindowを開くと、ボタンが表示されます。

f:id:notargs:20181210111143p:plain

インスペクタ拡張から使う

適当なHogeクラス用のインスペクタを作ってみます。

using UnityEngine;

public class Hoge : MonoBehaviour
{
}

OnInspectorGUIの代わりにCreateInspectorGUIを使い、戻り値としてインスペクタに描画してほしいVisualTreeを返します。

using UnityEditor;
using UnityEngine;
using UnityEngine.UIElements;

[CustomEditor(typeof(Hoge))]
public class HogeEditor : Editor
{
    public override VisualElement CreateInspectorGUI()
    {
        var visualElement = new VisualElement();
        var button = new Button(() => Debug.Log("Clicked!"))
        {
            text = "Click me"
        };
        visualElement.Add(button);
        return visualElement;
    }
}

問題なく動いてそうです!

f:id:notargs:20181210111631g:plain