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

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

GraphNodeBase类如下

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

Graph类如下

Copy
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

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

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

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

Copy
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类

Copy
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 @   jeoyao  阅读(792)  评论(0编辑  收藏  举报
编辑推荐:
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
阅读排行:
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!
点击右上角即可分享
微信分享提示