Unity学习笔记:数据持久化之Json(一)基础

前言

本篇为学习总结性质的文章,若发现任何问题或错误,欢迎在评论区指出。
如果本文对您有一定帮助,也欢迎点赞、收藏、关注。

目录

  • 前言
  • 概述
  • Json语法
    • 创建和编辑Json文件
    • Json注释
    • Json格式与规范
    • 举例
  • C#读取存储Json文件
    • 使用JsonUtility
      • 语法
      • 注意事项
    • 使用LitJson
      • 获取LitJson
      • 语法
      • 注意事项
    • 两者对比
      • 相同点
      • 不同点
  • 总结

概述

数据持久化是游戏中几乎必须要实现的东西,小到小游戏中最高分的记录,大到RPG游戏的存档系统对玩家Build、背包数据、剧情发展分支等的记录,都离不开数据持久化。

Json全称:JavaScript Object Notation(JavaScript对象简谱),是国际通用的一种轻量级的数据交换格式。
Json的优势在于易于人阅读和编写,同时也易于机器解析和生成,并有效提升网络传输效率

本文会从Json语法、JsonUtility、LitJson共三个方面来讲解。

Json语法

创建和编辑Json文件

Json本质上就是有着一套编写规则的文本,创建Json仅需右键新建文本文档,再将其后缀从txt改为json即可

Unity学习笔记:数据持久化之Json(一)基础_第1张图片

而编辑Json可以使用系统自带的记事本,简单方便、不用下载;也可以使用如Sublime Text等文本编辑器,或者一些网页上的Json编辑器,还可以帮助查错。

当然,在一般情况下我们是不会手动去编写Json文件的,但我们仍需要去了解Json的编辑方法及其语法。

Json注释

Json的注释与C#的注释一致:使用 // 来书写单行注释,使用/* */来包裹多行注释。

//单行注释
/*
多行
注释
*/

注意:如果严格根据Json规范,是不推荐添加注释的,这也是有时处理和读取Json会报错的原因。

Json格式与规范

首先我们必须要明确Json的基本结构,就像xml格式是一种树形结构一样,Json是一种键值对结构:
Unity学习笔记:数据持久化之Json(一)基础_第2张图片其中键只能是字符串,而值可以是字符串、数字、bool值、数组、对象以及null
而符号的基本规则是:
Unity学习笔记:数据持久化之Json(一)基础_第3张图片

举例

public class Item
{
	public int id;
	public int num;
	public Item(int id, int num)
	{
		this.id = id;
		this.num = num;
	}
}


public class PlayerInfo
{
	public string name;
	public int atk;
	public int def;
	public float moveSpeed;
	public Item weapon;
	public List listInt;
	public List itemList;
	public Dictionary itemDic;
}

如果我们需要配置一个以上玩家信息类对象,则可用Json描述为:

//为一个玩家信息类对象,所以最外层使用大括号包裹
{
	//具体值仅为举例
	//键只能为字符串,所以需包裹双引号
	"name":"张三",     
	"atk":10,		//使用逗号进行数据分割
	"def":3,		//可以不空行,但会减少可读性
	"moveSpeed":1.4,
	"weapon":{"id":1, "num":1},		//武器为一个item对象,所以也用大括号包裹
	//如果没有武器 可以直接复制为null
	"listInt":[1,2,3,4,5],			//中括号包裹数组
	"itemList":[{"id":2, "num":10},	//数组由一个个item对象组成,所以也用大括号包裹
				{"id":3, "num":99},
				{"id":4, "num":55}],
	"itemDic":{ "2":{"id":2, "num":1},	//虽然c#代码字典的键为int,但因为Json的特点,不得不使用string
				"3":{"id":3, "num":10}}	//注意末尾不要多加逗号
}

Json的语法是非常简单的,对照来看还是很清晰的。

C#读取存储Json文件

使用JsonUtility

JsonUtility是Unity自带的用于解析Json的公共类,可以用于Json文件的序列化与反序列化。

语法

//序列化
JsonUtility.ToJson( ); //传入对象,返回string,即对应的Json文本

//反序列化
JsonUtility.FromJson( , ); //传入Json字符串和Type,返回object(需要as成对应类)
JsonUtility.FromJson( ); //泛型类,只传入Json字符串,返回对应类

注意事项

序列化时:

  1. float序列化时看起来会有一些误差(但再反序列化误差会被忽略)
  2. 自定义类需要加上特性[System.Serializable]
  3. 私有变量需要加上特性[SerializeField]
  4. JsonUtility不支持字典
  5. JsonUtility存储null对象不会是null,而是默认值的数据

反序列化时:

  1. 文本编码格式需要是UTF-8,不然无法加载
  2. 如果Json中数据缺少,不会报错而是给默认值
  3. JsonUtlity无法直接读取数据集合(例如数组),需要包裹成类才能读取

使用LitJson

除Unity自带的JsonUtility外,也有很多优秀的第三方库可用于Json的序列化和反序列化。
LitJson体积小、易使用,是其中的优秀代表。

获取LitJson

要使用LitJson,可以去往其官网:https://litjson.net/
点击Source访问Github获取最新版本。Unity学习笔记:数据持久化之Json(一)基础_第4张图片只需拷贝核心代码到工程中即可使用:
Unity学习笔记:数据持久化之Json(一)基础_第5张图片

语法

//序列化
JsonMapper.ToJson( ); //传入对象,返回string,即对应的Json文本

//反序列化
JsonMapper.ToObject( ); //传入Json字符串和Type,返回JsonData
//JsonData是LitJson提供的类对象,可以用键值对的形式去访问其中的内容(具体可查阅官方文档)
JsonMapper.ToObject( ); //泛型类,传入Json字符串,返回对应类

注意事项

序列化时:

  1. 相对JsonUtility不需要加特性
  2. 不能序列化私有变量
  3. 支持字典类型,但字典的键建议都是字符串(避免由于Json的特点:Json中的键会加上双引号,导致出错)
  4. 需要引用LitJson命名空间(using LitJson;)
  5. LitJson可以准确的保存null类型

反序列化时:

  1. 自定义类结构需要无参构造函数,否则反序列化时报错。
    比如:
public class Item
{
	public int id;
	public int num;
	
	public Item(int id, int num)
	{
		this.id = id;
		this.num = num;
	}
}

C#中,有参构造函数会使默认的无参构造函数失效。所以如果这样写,我们再像之前示例一样去反序列化PlayerInfo,会报错。
我们需要为Item类手动添加无参构造函数:

public class Item
{
   public int id;
   public int num;
   
   public Item(){ }
   
   public Item(int id, int num)
   {
   	this.id = id;
   	this.num = num;
   }
}
  1. LitJson可以直接读取数据集合
    只需 JsonMapper.ToObject( ) 的T传入对应类型(数组、字典等)即可

  2. 同样,文本编码格式需要是UTF-8,不然无法加载

两者对比

相同点

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

不同点

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

总结

  1. Json的结构由键值对(键只能是字符串)构成,用 { } 包裹对象,用 [ ] 包裹数组,用逗号分隔数据
  2. JsonUtility和LitJson两者各有特点、优缺,根据需求进行选择使用

后续文章:Unity学习笔记:数据持久化之Json(二)Json序列化、反序列化简单工具编写

你可能感兴趣的:(Unity,unity,c#)