Unity编辑模式下如何序列化对象并实现对象字段与UI绑定
Unity 关卡编辑器JSON序列化与UI绑定兼容方案
核心矛盾本质是强行让同一份数据同时适配两套完全独立的序列化体系导致的,做职责拆分即可解决,以下是两种经过生产环境验证的落地方式:
方案1(推荐):POCO存储模型 + 编辑器绑定代理层
这个方案完全保留Unity SerializedObject 绑定的所有原生能力(撤销重做、UI自动布局、数组/嵌套类默认绘制、脏数据标记),同时彻底规避Unity对象被Newtonsoft序列化的所有兼容问题。
- 首先定义纯C#的POCO数据类,不继承任何Unity基类,所有字段仅服务于关卡数据存储,直接作为Newtonsoft序列化/反序列化的唯一目标:
// 运行时/存盘专用数据类,完全和Unity编辑逻辑解耦 public class Level { public string LevelName; // 其余关卡数据:比如怪物点位、道具配置、地形参数等 }
- 仅在编辑器程序集下定义和POCO字段一一对应的
ScriptableObject代理类,这个类只做UI绑定用,永远不参与JSON序列化、永远不打进运行时包:
#if UNITY_EDITOR using UnityEngine; public class LevelEditorProxy : ScriptableObject { public string LevelName; // 字段和Level类完全一一对应 } #endif
- 编辑器工作流逻辑:
- 加载JSON关卡时:先用Newtonsoft把JSON文本反序列化为纯POCO的
Level实例,创建一个LevelEditorProxy实例,通过反射/手动赋值把POCO的字段值同步到Proxy上,再用new SerializedObject(proxy)做UI绑定即可 - 保存关卡时:调用
_so.ApplyModifiedProperties()把UI修改同步到Proxy实例,再把Proxy的字段值同步回POCO的Level实例,最后用Newtonsoft把POCO序列化为JSON写入磁盘即可
- 加载JSON关卡时:先用Newtonsoft把JSON文本反序列化为纯POCO的
- 字段同步逻辑可以写一个通用的反射工具类,不需要每次新增字段都手动写映射,支持列表、嵌套类、值类型等绝大多数常用数据结构,一次编写永久复用。
方案2:绕开SerializedObject,直接绘制POCO字段
如果项目关卡数据结构简单,不需要SerializedObject自带的撤销、预制体关联等高级能力,可以完全绕开Unity的对象绑定要求,直接在EditorWindow里对POCO实例调用EditorGUI接口绘制:
// 不需要目标对象是UnityEngine.Object,直接读写POCO字段即可 _level.LevelName = EditorGUILayout.TextField("关卡名称", _level.LevelName);
- 如果需要Undo/Redo功能,可以在字段修改前自己记录POCO的修改前状态实现自定义撤销栈,灵活度更高,但是复杂数据结构(比如数组、嵌套类)的UI绘制需要自己手写逻辑,工作量随数据复杂度上升。
之前踩坑的原因说明
让Level继承MonoBehaviour/ScriptableObject后直接走Newtonsoft序列化抛出
rigidbody property has been deprecated报错,是因为Newtonsoft默认会序列化对象继承链上所有公开可访问的字段/属性,包括Unity基类内部定义的、已经在新版本被废弃的内置属性,就算手动加[JsonIgnore]屏蔽已知字段,后续Unity版本修改内部实现还是会出现新的序列化报错,完全没必要硬让Unity原生对象适配第三方JSON序列化流程。
额外注意点
- POCO类不要加任何Unity序列化相关特性(比如
[SerializeField]),私有字段需要JSON序列化的话加Newtonsoft的[JsonProperty]特性即可,和Unity序列化体系完全隔离,不会出现隐式的兼容问题。
内容的提问来源于stack exchange,提问作者Maxxx
相关产品推荐
相关产品推荐

