什么是数据持久化

数据持久化就是将内存中的数据模型转换为存储模型,以及将存储模型转换为内存中的数据模型的统称。

通俗解释:将游戏数据存储到硬盘,硬盘中的数据读取到游戏中,即传统意义上的存盘。


Json 介绍

全称: JavaScript 对象简谱(JavaScript Object Notation)

特点:

  • Json 是国际通用的一种轻量级的数据交换格式
  • 主要用于网络通讯中传输数据,或本地数据存储和读取
  • 易于人阅读和编写,同时也易于机器解析和生成,并有效地提升网络传输效率

用途:
我们一般使用 Json 文件来记录和传输数据。Json 文档就是使用 Json 格式配置填写的文档,后缀一般为 .json。在游戏中,可以把游戏数据按照 Json 格式标准存储在 Json 文档中,再将 Json 文档存储在硬盘上或者传输给远端,达到数据持久化或数据传输的目的。


Json 和 Xml 的异同

共同点:

  1. 都是纯文本
  2. 都有层级结构

不同点:

  1. Json 配置更简单,在某些情况下读写更快速。

Json 优缺点

优点:

  1. 跨平台:Json 是国际通用规则,可以在不同平台(游戏、软件、网页等)和操作系统中使用。
  2. 结构清晰:文件结构清晰易懂,非常容易编辑和理解,可用于网络通信交换数据。
  3. 数据配置:可以利用 Excel 转 Json 帮助策划进行数据配置。

缺点:

  1. 重复工作量大:自定义数据类都需要自己去实现存储读取的功能,且代码相似度较高。
  2. 数据容易被修改:只要找到文件位置,就可以轻易地进行数据修改。

Json 的主要用处

  • 网络游戏:存储客户端简单不重要数据,传输信息。
  • 单机游戏:存储游戏相关数据,配置游戏数据。

学习 Json 的意义和目标

  1. 增加一种存储和传输数据的选择。
  2. 增加一种配置数据的方法(具体会结合 UI 第三部曲讲解)。

目标:

  1. 掌握 Json 的基础规则。
  2. 掌握 C#读取存储 Json 文件。

Json 配置规则

用什么编辑 Json 文件?

任何能打开文档的软件都能打开 Json 文件。常用的编辑 Json 文件的方式包括:

  1. 系统自带:记事本、写字板
  2. 通用文本编辑器:Sublime Text 等等
  3. 网页上的 Json 编辑器

推荐使用 VSCode。

创建 Json 文件

直接右键创建文本,后缀改为 .json,选择自己喜欢的用于编辑 Json 的软件进行文本编辑。

JSON 语法规则

符号含义:

  • 大括号 {} —— 对象
  • 中括号 [] —— 数组
  • 冒号 : —— 键值对应关系
  • 逗号 , —— 数据分割
  • 双引号 “” —— 键名/字符串

键值对表示:

“键名”: 值内容

值类型:

  • 数字(整数或浮点)
  • 字符串
  • true 或 false
  • 数组
  • 对象
  • null

注意:Json 不支持注释(发明者要求 Json 应该简洁)。

示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
public class CCLing{
public string name;
public int age;
public bool sex;
public List<int> ids;
public List<Person> students;
public Home home;
public Person son;
public Dictionary<int, string> dic;
}

public class Person {
public string name;
public int age;
public bool sex;
}

public class Home {
public string address;
public string street;
}

变量名就是键,键用 "" 表示;冒号后面的内容就是值,值的类型不同表示不同。

注意:字典的键值对都是使用 "" 表示。

Json 文件示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
{
"name": "CCLing",
"age": 18,
"sex": true,
"testF": 1.4,
"ids": [1, 2, 3, 4, 5, 6],
"students": [
{ "name": "pps", "age": 10, "sex": false },
{ "name": "rsa", "age": 13, "sex": true }
],
"home": { "address": "上海", "street": "南京路" },
"son": null,
"dic": { "1": "123", "2": "234" }
}

配置 Json 文档时的注意事项

  1. 如果数据表示对象,那么最外层有大括号。
  2. 一定是键值对形式。
  3. 键一定是字符串格式。
  4. 键值对用逗号分开。
  5. 数组用 [] 包裹。
  6. 对象用 {} 包裹。

Excel 转 Json

在游戏开发中,使用 Excel 配置数据可以方便策划人员进行数据管理。通过在线工具,可以将 Excel 中的数据转换为 JSON 格式,以便将数据读取到内存中进行使用。

  1. 在 Excel 表中配置游戏数据

    • 列标题为属性名
    • 列元素为数据
  2. 使用在线工具转换为 JSON

优点:

  • 方便策划人员配置:Excel 界面直观,易于使用,策划人员可以轻松编辑和管理数据。
  • 简化数据转换:通过在线工具,可以快速将 Excel 数据转换为 JSON,减少手动编码的工作量。
  • 提高数据一致性:使用统一的 Excel 模板,可以保证数据格式的一致性,减少错误。
  • 便于数据持久化和传输:转换为 JSON 格式后,数据可以方便地存储在硬盘上或传输给远端服务器,实现数据持久化或网络传输。

JsonUtility 序列化/反序列化

JsonUtility 是什么?

JsonUtlity 是Unity 自带的用于解析 Json 的公共类

它可以:

  1. 将内存中对象序列化为 Json 格式的字符串
  2. 将 Json 字符反序列化为类对象

在文件中读写字符串

使用 File.WriteAllTextFile.ReadAllText

需要使用命名空间 System.IO

1
2
3
4
5
6
7
8
//1、存储字符串到指定路径文件中
//参数一:存储的路径+/文件名
//参数二:存储的字符串的内容
File.WriteAllText(Application.streamingAssetsPath + "/Test.json", "Panzi");

//2、在指定路径文件中读取字符串
//参数一:存储的路径+/文件名
string str = File.ReadAllText(Application.streamingAssetsPath + "/Test.json");

使用 JsonUtility 进行序列化

序列化:把内存中的数据,存储到硬盘上。

使用 JsonUtility.ToJson(obj) 方法即可。

注意:

  1. float 序列化时看起来会有一些误差(实际读出来就正常了)
  2. 自定义类需要加上序列化特性 [System.Serializable]
  3. 想要序列化私有变量,需要加上特性 [SerializeField]
  4. JsonUtlity 不支持字典序列化(和 XmlSerializer 一样)
  5. JsonUtlity 存储 null 对象不会是 null,而是默认值数据
1
2
3
Data d = new Data();
string ret = JsonUtility.ToJson(d);
File.WriteAllText(Application.streamingAssetsPath + "/Test.json", ret);

使用 JsonUtility 进行反序列化

反序列化:把硬盘上的数据读取到内存中

使用 JsonUtility.FromJson(string, type)方法即可(支持泛型)

1
2
3
ret = File.ReadAllText(Application.streamingAssetsPath + "/Test.json");
Data data = JsonUtility.FromJson(ret, typeof(Data)) as Data;
data = JsonUtility.FromJson<Data>(ret);

注意:如果 Json 当中内容少了,不会报错,会设置为类型默认值。

知识点五 注意事项

  1. JsonUtility 无法直接读取数据集合,可以使用一个类包裹来读取

    1
    List<Data> datas = JsonUtility.FromJson<List<Data>>(ret);   //无法读取
  2. 文本编码格式需要是 UTF-8,不然无法加载

总结

  1. 必备知识点一 File 存读专符串的方法 ReadAllText 和 writeAllText
  2. JsonUtlity 提供的序列化反序列化方法 ToJson 和 FromJson
  3. 自定义类需要加上序列化特性[System.Serializable]
  4. 私有保护成员需要加上[serializeField]
  5. JsonUtlity 不支持字典
  6. JsonUtlity 不能直接将数据反序列化为数据集合
  7. Json 文档编码格式必须是 UTF-8

LitJson 序列化

知识点一 LitJson 是什么

它是一个第三方库,用于处理 Json 的序列化和反序列化
LitJson 是 C# 编写的,体积小、速度快、易于使用
它可以很容易的嵌入到我们的代码中
只需要将 LitJson 代码拷贝到工程中即可

知识点二 获取 LitJson

  1. 前往 LitJson 官网
  2. 通过官网前往 GitHub 获取最新版本代码
  3. 将代码拷贝到 Unity 工程中即可开始使用 LitJson

知识点三 序列化

  1. 相对 JsonUtlity 不需要加特性
  2. 不能序列化私有变量
  3. 支持字典类型,字典的键建议都是字符串因为 Json 的特点 Json 中的键会加上双引号
  4. 需要引用 LitJson 命名空间
  5. LitJson 可以准确的保存 null 类型

使用 JsonMapper.ToJson(obj),返回字符串,然后将字符串写入文件即可。

1
2
3
DataInfo data = new DataInfo();
string str = JsonMapper.ToJson(data);
File.WriteAllText(Application.streamingAssetsPath + "/Test2.json", str);

知识点四 反序列化

使用 JsonMapper.ToObject(字符串),支持泛型

注意:

  1. 类结构需要无参构造函数,否则反序列化时报错
  2. 字典虽然支持但是键在使用为数值时会有问题需要使用字符串类型
1
2
3
4
5
str = File.ReadAllText(Application.streamingAssetsPath + "/Test2.json");
JsonData data = JsonMapper.ToObject(str);
print(data["age"]);

d = JsonMapper.ToObject<DataInfo>(str);

知识点五 注意事项

  1. LitJson 可以直接读取数据集合
  2. 文本编码格式需要是UTF-8,不然无法加载

总结

  1. LitJson 提供的序列化反序列化方法JsonMapper.ToJsonToObject(支持泛型)
  2. LitJson 无需加特性
  3. LitJson 不支持私有变量
  4. LitJson 支持字典序列化反序列化
  5. LitJson 可以直接将数据反序列化为数据集合
  6. LitJson 反序列化时自定义类型需要无参构造
  7. json 文档编码格式必须是 UTF-8

JsonUtility 和 LitJson 对比

相同点

  1. 他们都是用于 Json 的序列化反序列化
  2. Json 文档编码格式必须是 UTF-8
  3. 都是通过静态类进行方法调用

不同点

  1. JsonUtility 是 Unity 自带,LitJson 是第三方需要引用命名空间
  2. JsonUtility 使用时自定义类需要加特性,LitJson 不需要
  3. JsonUtility 支持私有变量(加特性),LitJson 不支持
  4. JsonUtility 不支持字典,LitJson 支持(但是键只能是字符串)
  5. JsonUtility 不能直接将数据反序列化为数据集合(数组字典),LitJson 可以
  6. JsonUtility 对自定义类不要求有无参构造,LitJson 需要
  7. JsonUtility 存储空对象时会存储默认值而不是 null,LitJson 会存 null

使用建议

根据实际需求

建议使用 LitJson

原因:LitJson 不用加特性,支持字典,支持直接反序列化为数据集合,存储 null 更准确