AssetGraphTool拡張の際につまずいた話

こんにちは。カヤックアキバスタジオでエンジニアをやっている瀬尾です。

この記事は 面白法人グループ Advent Calendar 2022 の10日目の記事です。

今回はUnityのAssetGraphToolを使った時のお話です。

つまずいた箇所

List形式のデータを追加し、シリアライズしたListをインスペクターに追加することは簡単でしたが、
再起動した際に状態が保存されませんでした。
調査したところ、 SerializedInstanceというクラスが用意されているようです。

動作するようにしたサンプル

using UnityEditor;
using System;

namespace UnityEngine.AssetGraph
{
    public interface ISample
    {
        void OnInspectorGUI(Rect rect, Action onValueChanged);
    }

    [System.Serializable]
    public class SampleInstance : SerializedInstance
    {

        public SampleInstance() : base() { }
        public SampleInstance(SampleInstance instance) : base(instance) { }
        public SampleInstance(ISample obj) : base(obj) { }
    }

    [Serializable]
    public class SampleData
    {
        [SerializeField] private SampleInstance m_instance;

        public SampleData(ISample sample)
        {
            m_instance = new SampleInstance(sample);
        }

        public SampleData(SampleData e)
        {
            m_instance = new SampleInstance(e.m_instance);
        }

        public SampleInstance Instance
        {
            get
            {
                return m_instance;
            }
            set
            {
                m_instance = value;
            }
        }

        public string Hash
        {
            get
            {
                return m_instance.Data;
            }
        }
    }
}

ノードで実際に使用するクラス定義

namespace UnityEngine.AssetGraph
{
    public class Sample : ISample
    {
        [SerializeField] private string m_keyword;
        [SerializeField] private string m_parameterKey;

        public Sample()
        {
            m_keyword = "";
            m_parameterKey = "";
        }

        public Sample(string name)
        {
            m_keyword = name;
        }

        public void OnInspectorGUI(Rect rect, Action onValueChanged)
        {
            var keyword = m_keyword;
            var parameter = m_parameterKey;

            GUIStyle s = new GUIStyle((GUIStyle)"TextFieldDropDownText");

            Rect filerKeywordRect = rect;
            Rect parameterRect = rect;
            filerKeywordRect.width = 120f;
            parameterRect.x += 124f;
            parameterRect.width = 124f;

            keyword = EditorGUI.TextField(filerKeywordRect, m_keyword, s);
            parameter = EditorGUI.TextField(parameterRect, m_parameterKey, s);
            if (keyword != m_keyword)
            {
                m_keyword = keyword;
                onValueChanged();
            }
            if (parameter != m_parameterKey)
            {
                m_parameterKey = parameter;
                onValueChanged();
            }
        }
    }
}

あとは表示するノード側のOnInspectorGUIで、表示処理を呼び出すことで表示されます。
また、状態の保存も問題無く実行されました。

まとめ

かなり簡単に実装することができました。
Editorはそれほど手を出していなかったので
これからもうすこし拡張機能に挑戦してみようと思います。