在开始讲解这一章节前,我们需要了解,什么是 Json.
Json
他的全称是 JavaScript Object Notation 【JavaScript 对象表示法】
JSON 是存储和交换文本信息的语法
。类似 XML。json是基于ECMAScript
语法,但这并不意味着 json 必须在 js 中使用,或者必须要产生什么联系, json 在 js 中的处理也并没有比其他语言占有更多优势。只是因为语法相似,而使得js开发者能更快的上手 json 而已。
JSON采用完全独立于任何程序语言的文本格式,但是也使用了类似于 C 语言家族的习惯(包括 C、C++、C#、Java、JavaScript、Perl、Python 等)。这些特性使 JSON 成为理想的数据交换语言。易于人阅读和编写,同时也易于机器解析和生成,并有效地提升网络传输效率。
典型的 Json 数据
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| 对象: { "name": "火球术", "cost": 1, "Owner": "法师" }
数组: ["hello",3.1415,"json"]
数组嵌套对象: [{"name":"admin","age":18}, {"name":"root","age":16}, {"name":"张三","age":20}]
|
Json 语法规则
- 数据在
键值对
中
- 数据由逗号 , 分隔
- 使用斜杆 \ 来转义字符
- 大括号 {} 保存对象
- 中括号 [] 保存数组,数组可以包含多个对象
json 的值
- 数字(整数或浮点数)
- 字符串(在双引号中)
- 逻辑值(true 或 false)
- 数组(在中括号中)
- 对象(在大括号中)
- null
JsonUtility
JsonUtility 是 Unity 提供的一个工具类,用于序列化和反序列化 Json 数据。
使用方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| string json = JsonUtility.ToJson(obj);
myObject = JsonUtility.FromJson<T>(json);
FromJsonOverwrite(string text, object objectToOverwrite)
ToJson(object target, bool prettyPrint) target:对象转换为 Json 数据文本 prettyPrint:决定最终的 Json 数据文本是否是一个格式化后的数据文本。 即是否使用 Json 文本的 Format 化。
FromJson(string text) 将 Json 数据文本转存至类中 public 或 附有 SerializeField 特性的字段上赋值。 使用时无需管理值具体分配。其将基于字段命名自行匹配并赋值。 此代码将创建一个新的 T 实例,并使用 JSON 数据设置该实例的值。如果 JSON 数据包含的某些值未映射到 T 中的字段,则序列化程序将忽略这些值。如果 JSON 数据缺少 T 中某些字段的值,则序列化程序会在返回的对象中保留这些字段的构造值。
FromJsonOverwrite(string text, object objectToOverwrite) 在现有对象上反序列化 JSON 数据,从而覆盖所有现有数据。 使用时无需管理值具体分配。其将基于字段命名自行匹配并赋值。 如果 JSON 数据不包含某个字段的值,则序列化程序不会更改该字段的值。 JSON 序列化程序 API 支持 MonoBehaviour 和 ScriptableObject 子类以及普通结构和类。但是,将 JSON 反序列化为 MonoBehaviour 或 ScriptableObject 子类时,必须使用 FromJsonOverwrite 方法。如果尝试使用 FromJson,则 Unity 会抛出异常,因为不支持此行为。
|
注意事项
- 仅支持 MonoBehaviour / ScriptableObject 继承类的序列化
- 仅支持 [Serializable] 的普通类与结构体
- 仅序列化 public 或 [SerializeField] 标签的字段
- 在内部,此方法使用 Unity 序列化器;因此传入的对象必须受序列化器支持:它必须是 MonoBehaviour、ScriptableObject 或应用了 Serializable 属性的普通类/结构。要包含的字段的类型必须受序列化器支持;不受支持的字段以及私有字段、静态字段和应用了 NonSerialized 属性的字段会被忽略。
- 支持 List、Array 数据类型,但不支持 Dictionary、Query、Stack 等集合
- 支持 Enum 枚举,但默认存储值为数值类型
字典的序列化和反序列化
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50
| using System.Collections.Generic; using UnityEngine; using System;
public class SerializeDictionary { public static string DicToJson<TKey, TValue>(Dictionary<TKey, TValue> dic) { return JsonUtility.ToJson(new SerializeDictionary<TKey, TValue>(dic)); }
public static Dictionary<TKey, TValue> DicFromJson<TKey, TValue>(string str) { return JsonUtility.FromJson<SerializeDictionary<TKey, TValue>>(str).ToDictionary(); } }
[Serializable] public class SerializeDictionary<TKey, TValue> : ISerializationCallbackReceiver { [SerializeField] List<TKey> keys; [SerializeField] List<TValue> values;
Dictionary<TKey, TValue> target; public Dictionary<TKey, TValue> ToDictionary() { return target; }
public SerializeDictionary(Dictionary<TKey, TValue> target) { this.target = target; }
public void OnBeforeSerialize() { keys = new List<TKey>(target.Keys); values = new List<TValue>(target.Values); }
public void OnAfterDeserialize() { var count = Math.Min(keys.Count, values.Count); target = new Dictionary<TKey, TValue>(count); for (var i = 0; i < count; ++i) { target.Add(keys[i], values[i]); } } }
|
本文作于2023-08-21,首发于个人博客https://rdququ.top/