Unity数据持久化3——Json

概述

基础知识

Json文件格式

Json基本语法

练习

可以搜索:Json在线,复制代码进去解析是否写错了。

Excel转Json

C#读取存储Json文件

JsonUtility

using System.Collections;
using System.Collections.Generic;
using System.IO;
using UnityEngine;

[System.Serializable]
public class Student
{
    public int age;
    public string name;

    public Student(int age, string name)
    {
        this.age = age;
        this.name = name;
    }
}

public class Player
{
    public string name;
    public int age;
    public bool sex;
    public float testF;
    public double testD;

    public int[] ids;
    public List<int> ids2;
    public Dictionary<int, string> dic;
    public Dictionary<string, string> dic2;

    public Student s1;
    public List<Student> s2s;

    [SerializeField]
    private int privateI = 1;
    [SerializeField]
    protected int protectedI = 2;
}

public class RoleData
{
    public List<RoleInfo> list;
}

[System.Serializable]
public class RoleInfo
{
    public int hp;
    public int speed;
    public int volume;
    public string resName;
    public int scale;
}


public class Lesson1 : MonoBehaviour
{
    // Start is called before the first frame update
    void Start()
    {
        #region 知识点一 JsonUtility是什么
        //JsonUtility 是Unity自带的用于解析Json的公共类
        //它可以
        //1.将内存中对象序列化为Json格式的字符串
        //2.将Json字符串反序列化为类对象
        #endregion

        #region 知识点二 必备知识点——在文件中存读字符串
        //1.存储字符串到指定路径文件中
        //第一个参数 填写的是 存储的路径
        //第二个参数 填写的是 存储的字符串内容
        //注意:第一个参数 必须是存在的文件路径 如果没有对应文件夹 会报错
        File.WriteAllText(Application.persistentDataPath + "/Test.json", "Sunset存储的json文件");
        print(Application.persistentDataPath);

        //2.在指定路径文件中读取字符串
        string str = File.ReadAllText(Application.persistentDataPath + "/Test.json");
        print(str);

        #endregion

        #region 知识点三 使用JsonUtility进行序列化
        //序列化:把内存中的数据 存储到硬盘上
        //方法:
        //JsonUtility.ToJson(对象)
        Player p = new Player();
        p.name = "Sunset";
        p.age = 18;
        p.sex = true;
        p.testF = 1.5f;
        p.testD = 2.2;

        p.ids = new int[] { 1, 2, 3, 4, 5 };
        p.ids2 = new List<int>() { 1, 2, 3 };
        p.dic = new Dictionary<int, string>() { { 1, "123" }, { 2, "234" } };
        p.dic2 = new Dictionary<string, string> { { "3", "345" }, { "4", "456" } };
        p.s1 = null; //new Student(16, "Jack");
        p.s2s = new List<Student> { new Student(17, "Mary"), new Student(20, "Tom") };

        //JsonUtility提供了现成的方法 可以把类对象 序列化为 Json字符串
        string jsonStr = JsonUtility.ToJson(p);
        File.WriteAllText(Application.persistentDataPath + "/Player.json", jsonStr);

        //注意:
        //1.float序列化时看起来会有一些误差
        //2.自定义类需要加上序列化特性[System.Serializable]
        //3.想要序列化私有变量 需要加上特性[SerializeField]
        //4.JsonUtility不支持字典
        //5.IsonUtility存储null对象不会是null 而是默认值的数据
        #endregion

        #region 知识点四 使用JsonUtility进行反序列化
        //反序列化:把硬盘上的数据 读取到内存中
        //方法:
        //JsonUtility.FromJson(字符串)
        //读取文件中的 Json字符串
        jsonStr = File.ReadAllText(Application.persistentDataPath + "/Player.json");
        //使用Json字符串内容 转换成类对象
        Player p2 = JsonUtility.FromJson(jsonStr, typeof(Player)) as Player; //这种写法比较少用
        Player p3 = JsonUtility.FromJson<Player>(jsonStr); //这个写法常用

        //注意:
        //如果Json中数据少了,读取到内存中类对象中时不会报错
        #endregion

        #region 知识点五 注意事项
        //1.JsonUtilitu无法直接读取数据集合
        jsonStr = File.ReadAllText(Application.streamingAssetsPath + "/RoleInfo2.json");
        print(jsonStr);
        //List<RoleInfo> roleInfoList = JsonUtility.FromJson<List<RoleInfo>>(jsonStr);
        RoleData data = JsonUtility.FromJson<RoleData>(jsonStr);

        //2.文件编码格式需要是 UTF-8 不然无法加载
        #endregion

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

    }

    // Update is called once per frame
    void Update()
    {
        
    }
}

练习:

LitJson

using LitJson;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using UnityEngine;

public class Item2
{
    public int id;
    public int num;

    //LitJson反序列化时 自定义类型需要无参构造
    public Item2() { }

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

public class PlayerInfo2
{
    public string name;
    public int atk;
    public int def;
    public float moveSpeed;
    public double roundSpeed;
    public Item2 weapon; 
    public List<int> listInt;
    public List<Item2> itemList;
    //public Dictionary<int, Item2> itemDic;
    public Dictionary<string, Item2> itemDic2;
}

public class Lesson2_Test : MonoBehaviour
{
    // Start is called before the first frame update
    void Start()
    {

        PlayerInfo2 p = new PlayerInfo2();
        p.name = "Sunstet";
        p.atk = 10;
        p.def = 3;
        p.moveSpeed = 20;
        p.roundSpeed = 20;
        p.weapon = new Item2(1, 10);
        p.listInt = new List<int>() { 1, 2, 3, 4, 5 };
        p.itemList = new List<Item2>() { new Item2(2, 20), new Item2(3, 30) };
        //p.itemDic = new Dictionary<int, Item2>() { { 1, new Item2(4, 40) }, { 2, new Item2(5, 50) } };
        p.itemDic2 = new Dictionary<string, Item2> { { "3", new Item2(6, 60) }, { "4", new Item2(7, 70) } };

        SaveData(p, "PlayerInfo2");

        PlayerInfo2 p2 = LoadData("PlayerInfo2");

    }

    public void SaveData(PlayerInfo2 p, string path)
    {
        string jsonStr = JsonMapper.ToJson(p);
        File.WriteAllText(Application.persistentDataPath + "/" + path + ".json", jsonStr);
        print(Application.persistentDataPath);
    }

    public PlayerInfo2 LoadData(string path)
    {
        string jsonSr = File.ReadAllText(Application.persistentDataPath + "/" + path + ".json");
        return JsonMapper.ToObject<PlayerInfo2>(jsonSr);
    }
}

JsonUtility 和 LitJson对比

总结

实践项目

需求分析 + Json数据管理类创建

存储和读取数据

using LitJson;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using UnityEngine;

/// <summary>
/// 序列化和反序列化Json时 使用的是哪种方案
/// </summary>
public enum JsonType
{
    JsonUtility,
    LitJson,
}

/// <summary>
/// Json数据管理类 主要用于进行 Json的序列化存储到硬盘 和 反序列化从硬盘中读取到内存中
/// </summary>
public class JsonMgr 
{
    private static JsonMgr instance = new JsonMgr();

    public static JsonMgr Instance => instance;

    public JsonMgr() { }

    //存储Json数据 序列化
    public void SaveData(object data, string fileName, JsonType type = JsonType.LitJson)
    {
        #region 自己写
        //string jsonStr = "";
        //switch (type)
        //{
        //    case JsonType.JsonUtility:
        //        jsonStr = JsonUtility.ToJson(data);
        //        break;
        //    case JsonType.LitJson:
        //        jsonStr = JsonMapper.ToJson(data);
        //        break;
        //}

        //File.WriteAllText(Application.persistentDataPath + "/" + fileName + ".json", jsonStr);

        #endregion

        //确定存储路径
        string path = Application.persistentDataPath + "/" + fileName + ".json";
        //序列化 得到Json字符串
        string jsonStr = "";
        switch (type)
        {
            case JsonType.JsonUtility:
                jsonStr = JsonUtility.ToJson(data);
                break;
            case JsonType.LitJson:
                jsonStr = JsonMapper.ToJson(data);
                break;
        }
        //把序列化的Json字符串 存储到指定路径的文件中
        File.WriteAllText(path, jsonStr);
    }

    /// <summary>
    /// 读取指定文件中的数据 反序列化
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="fileName"></param>
    /// <param name="type"></param>
    /// <returns></returns>
    public T LoadData<T>(string fileName, JsonType type = JsonType.LitJson) where T : new()
    {
        //确定从哪个路径读取
        //首先先判断 默认数据文件夹中是否有我们想要的数据 如果有 就从中获取
        string path = Application.streamingAssetsPath + "/" + fileName + ".json";
        //先判断 是否重载这个文件
        //如果不存在默认文件 就从 读写文件夹中去寻找
        if (!File.Exists(path))
            path = Application.persistentDataPath + "/" + fileName + ".json";
        //如果读写文件夹中都还没有 那就返回一个默认对象
        if (!File.Exists(path))
            return new T();

        //进行反序列化
        string jsonStr = File.ReadAllText(path);

        //把对象返回出去

        //数据对象
        T data = default(T);
        switch (type)
        {
            case JsonType.JsonUtility:
                data = JsonUtility.FromJson<T>(jsonStr);
                break;
            case JsonType.LitJson:
                data = JsonMapper.ToObject<T>(jsonStr);
                break;
        }

        return data;
    }

}

生成资源包

挖坑总结

  • 12
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值