unity数据持久化-json

JsonUtlity

JsonUtlity是unity自带的序列化和反序列化工具类,主要提供了两个方法ToJsonFromJson

ToJson序列化

比如我们有一个类是这样的

class Person1
{
    public int testI;
    public float testF;
    public double testD;
    public string testS;
    public int[] testArr;
    public List<int> testList;
    public Dictionary<int, string> testDic;
    public Person2 testObj;
    private int testPri = 1;
}

class Person2
{
    public string name;
    public int age;
}

其中包括大部分常用的数据类型,我们可以通过JsonUtlity提供的ToJson Api来实现序列化

Person1 p = new Person1();
p.testI = 18;
p.testF = 1.22f;
p.testD = 1.22;
p.testS = "XXX";
p.testArr = new[] { 1, 2, 3 };
p.testList = new List<int>() { 1, 2, 3 };
p.testDic = new Dictionary<int, string>() { { 1, "test" } };
p.testObj = new Person2() { name = "xxx", age = 18 };
print(JsonUtility.ToJson(p));

//out:
{"testI":18,"testF":1.2200000286102296,"testD":1.22,"testS":"XXX","testArr":[1,2,3],"testList":[1,2,3]}

结果中没有包含

  • 私有的成员
  • dictionary类型
  • 自定义class

在System名称空间中提供了两个特性

[Serializable] //用于标识序列化class
[SerializeField] //用于标识序列化成员

为上述两个类补充上这序列化的特性

[Serializable]
class Person2{
    ...
}

Class Person1{
    ...
    [Serializable]
    private int testPri = 1;
}

再次运行发现除了Dictionary类型之外都能为序列化

FromJson反序列化

通过序列化得到的json字符串

{"testI":18,"testF":1.2200000286102296,"testD":1.22,"testS":"XXX","testArr":[1,2,3],"testList":[1,2,3],"testObj":{"name":"xxx","age":18},"testPri":1}

可以通过

JsonUtility.FromJson<Type>(jsonStr);

来反序列化

image-20240202113910354

{"testI":18,"testF":1.2200000286102296,"testD":1.22,"testS":"XXX","testArr":[1,2,3],"testList":[1,2,3],"testObj":{"name":"xxx","age":18},"testPri":1}

JsonUtlity序列化的不足

无法序列化Dictionary类型

未赋值的成员变量会使用对应的默认值

Person1 p = new Person1();
string jsonStr = JsonUtility.ToJson(p);
print(jsonStr);
//out:
{"testI":0,"testF":0.0,"testD":0.0,"testS":"","testArr":[],"testList":[],"testObj":{"name":"","age":0},"testPri":1}

可以看到,我们在没有对p进行赋值的情况下,它的所有能被序列化的成员都使用了各自的默认值

无法直接读取数据集合

比如我们有一段json格式字符串

[
    {"hp":10,"attack":5},
    {"hp":20,"attack":5},
    {"hp":30,"attack":5}
]

​ 数组的每一个元素为一个对象

class GameObj{
 public int hp;
 public int attack;
}

使用FromJson反序列化的时候会报错

string jsonStr =
            "[\n    {\"hp\":10,\"attack\":5},\n    {\"hp\":20,\"attack\":5},\n    {\"hp\":30,\"attack\":5}\n]";
GameObj[] arr = JsonUtility.FromJson<GameObj[]>(jsonStr);
print(arr);

//ArgumentException: Return type must represent an object type. Received an array.

总结

  • JsonUtlity提供的序列化反序列化方法 ToJson 和 FromJson
  • 自定义类需要加上序列化特性[System.Serializable]
  • 私有保护成员 需要加上[SerializeField]
  • JsonUtlity不支持字典
  • JsonUtlity不能直接将数据反序列化为数据集合

LitJson

LitJson和JsonUtlity一样属于第三方json序列化工具

获取litJson

github: GitHub - LitJSON/litjson: JSON library for the .Net framework

下载之后解压将下面文件夹拖入unity中

image-20240202143129292

使用litjson序列化

api:

JsonMapper.ToJson(obj)

准备一个测试序列化的类

class Test
{
    public int testI;
    public float testF;
    public string testS;
    public List<int> testList;
    public Dictionary<string, string> testDic;
    public Person testP;
    private int testPri = 1;
}

new一个对象并给所有成员变量赋值

Test t = new Test();
t.testI = 1;
t.testF = 1.2f;
t.testS = "hello";
t.testList = new List<int>() { 1, 2, 3, 4 };
t.testDic = new Dictionary<string, string>() { {"1","name"} };
t.testP = new Person();
print(JsonMapper.ToJson(t));

//out:
{"testI":1,"testF":1.2,"testS":"hello","testList":[1,2,3,4],"testDic":{"1":"name"},"testP":{"name":null,"age":0}}

和JsonUtlity不同是的,LitJson不用给Person 类添加特性使其可以被序列化,字典类型可以正常的被序列化,但是私有字段无法被支持

除此之外,如果我们不给 t.testP 赋值

那么序列化出来的结果

t.testP 赋值

//out
{"testI":1,"testF":1.2,"testS":"hello","testList":[1,2,3,4],"testDic":{"1":"name"},"testP":null}

那么testP 的结果便为null,而JsonUtlity则会生成一个多有成员都是默认值的对象

LitJson反序列化

api :

JsonMapper.ToObject<Test>(jsonStr)

使用序列化的json字符串进行反序列化

{"testI":1,"testF":1.2,"testS":"hello","testList":[1,2,3,4],"testDic":{"1":"name"},"testP":{"name":null,"age":0}}

image-20240202145307975

注意

类成员中自定义的class对象需要无参构造函数,否则反序列化会报错

字典只能是string类型作为键

可以直接序列化集合类型

总结

  • LitJson提供的序列化反序列化方法 JsonMapper.ToJson和ToObject<>
  • LitJson无需加特性
  • LitJson不支持私有变量
  • LitJson支持字典序列化反序列化
  • LitJson可以直接将数据反序列化为数据集合
  • LitJson反序列化时 自定义类型需要无参构造
posted @   mress  阅读(103)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!
点击右上角即可分享
微信分享提示