Unity开发笔记-使用AssetDatabase.AddObjectToAsset函数,正确序列化ScriptableObject的多态数组,修复TypeMissMatch错误

假设我们需要使用ScriptableObject来保存一个图的结构,我们先创建2个ScriptableObject的子类,Graph和GraphNodeBase

GraphNodeBase类如下

namespace YaoJZ.SerializeTest
{
    public class GraphNodeBase:ScriptableObject
    {
        
    }
}

Graph类如下

namespace YaoJZ.SerializeTest
{
    [CreateAssetMenu(fileName = "graph.asset",menuName = "yaojz/graph")]
    public class Graph:ScriptableObject
    {
        public List<GraphNodeBase> Nodes;

        public void AddNode(GraphNodeBase node)
        {
            Nodes.Add(node);
        }
    }
}

我们需要根据需求扩展GraphNodeBase的子类,比如AnimationClipNode

namespace YaoJZ.SerializeTest
{
    public class AnimationClipNode:GraphNodeBase
    {
        public AnimationClip Clip;
    }
}

我们需要CreateAssetMenu用来创建Graph.asset资产

现在我们需要扩展一下Graph的Inspector,增加一个按钮,用来添加节点,用来添加AnimationClipNode


namespace YaoJZ.SerializeTest.Editor
{
    [CustomEditor(typeof(Graph))]
    public class GraphInspector:UnityEditor.Editor
    {
        public override void OnInspectorGUI()
        {
            base.OnInspectorGUI();
            if (GUILayout.Button("add animation node"))
            {
                Graph g = this.target as Graph;
                g.AddNode(ScriptableObject.CreateInstance<AnimationClipNode>());
            }
        }
    }
}

现在我们点击一下按钮

出现了TypeMissMatch,这显然不是我们想要的AnimationClipNode,原因是ScriptableObject只能引用资产,引用了未被序列化的对象就会出现这个问题。因此结论是我们没有正确序列化AnimationClipNode,因为CreateInstance只是创建再内存中,并没有保存到磁盘里。

解决方案很简单,只需要AssetDatabase.AddObjectToAsset,将AnimationClipNode嵌入到已被序列化好的Graph中即可

更新后的Graph类


public class Graph:ScriptableObject
    {
        public List<GraphNodeBase> Nodes;

        public void AddNode(GraphNodeBase node)
        {
            AssetDatabase.AddObjectToAsset(node,this);      //将node序列化,并嵌入graph对象中
            if (Nodes == null)
            {
                Nodes = new List<GraphNodeBase>();
            }
            Nodes.Add(node);
        }
    }

按一下ctrl+s保存下项目,查看graph.asset,就可以发现node已作为孩子节点被序列化在graph中了

posted @ 2021-02-19 20:47  jeoyao  阅读(650)  评论(0编辑  收藏  举报