Json数据持久化

Unity Json 数据持久化

1.序列化和反序列化的两种方案JsonUtility(Unity内置 不推荐)、LitJson(需要导入第三方代码文件 推荐使用)

特性 JsonUtility(Unity 内置) LitJson(第三方推荐)
字典支持 ❌ 不支持字典 ✅ 支持字典(键必须是 string)
null 值支持 ❌ 对象 null 会变成默认值 ✅ 支持 null
集合最外层 必须是对象 {} 可以是数组 []
私有变量支持 [SerializeField] ❌ 不支持私有变量
自定义类特性 [System.Serializable] ❌ 不需要特性,但类必须有无参构造函数

使用JsonUtility和LitJson时,数据结构区别

//JsonUtility 必须定义PlayerData,PlayerData里面声明playerList列表
//PlayerData和PlayerInfo是自定义类,JsonUtility必须使用[System.Serializable]
[System.Serializable]
public class PlayerData
{
    public List<PlayerInfo> playerList;  // 集合必须放在对象里
}
[System.Serializable]
public class PlayerInfo
{
    public string playerName;
    public int level;
}

//LitJson 有两种方式
//第一种 和JsonUtility一样 定义类包裹玩家信息集合(不推荐)
public class PlayerData
{
    public List<PlayerInfo> playerList;  // 集合必须放在对象里
}
public class PlayerInfo
{
    public string playerName;
    public int level;
}

//第二种 直接定义玩家信息(推荐 Excel转Json 就是这种数据格式)
public class PlayerInfo
{
    public string playerName;
    public int level;
}

使用JsonUtility和LitJson时,配置文件格式\导出文件格式区别(配置文件使用Excel转Json 不用手动编写Json)

  • 最后一条数据不能有 ","
//JsonUtility只有一种格式
//以类的格式读取数据(没有定义PlayerData类就不能够使用)
{
  "playerList": 
  [
    {"playerName": "Alice", "level": 5},
    {"playerName": "Bob", "level": 10},
    {"playerName": "Charlie", "level": 8}
  ]
}

//LitJson 有两种格式
//第一种,以类的格式读取数据(没有定义PlayerData类就不能够使用)
{
  "playerList": 
  [
    { "playerName": "Alice", "level": 5 },
    { "playerName": "Bob", "level": 10 },
    { "playerName": "Charlie", "level": 8 }
  ]
}

//第二种,省略列表类,自定义列表格式读取数据(无论是否定义PlayerData类都可以使用 需要自己定义List<PlayerInfo> playerList接收)
[
  { "playerName": "Alice", "level": 5 },
  { "playerName": "Bob", "level": 10 },
  { "playerName": "Charlie", "level": 8 }
]

使用JsonUtility和LitJson时,反序列化数据的区别

// JsonUtility只有一种反序列化数据的方式
//只能以对象形式读取数据
PlayerData playerData = JsonDataMgr.Instance.Load<PlayerData>("PlayerData");

//LitJson有两种反序列化数据的方式
//第一种 以对象形式读取数据(不推荐)
PlayerData playerData = JsonDataMgr.Instance.Load<PlayerData>("PlayerData");

//第二种 以自定义列表格式读取数据(推荐 Excel转Json 就是这种数据格式)
List<PlayerInfo> playerList = JsonDataMgr.Instance.Load<List<PlayerInfo>>("PlayerData");

2. 通用的 Json 管理器:JsonDataMgr(支持序列化、反序列字典数据)

using LitJson;
using System;
using System.IO;
using UnityEngine;
/// <summary>
/// 序列化和反序列化json时 使用的是哪种方案
/// </summary>
public enum JsonType
{
    JsonUtility,
    LitJson,
}
/// <summary>
/// Json数据管理 主要用于 Json的序列化到硬盘 和 反序列化从硬盘读取到内存中
/// </summary>
public class JsonDataMgr
{
    private static JsonDataMgr instance = new JsonDataMgr();
    public static JsonDataMgr Instance => instance;
    private JsonDataMgr() { }
    public void SaveData(object data,string fileName,JsonType type=JsonType.LitJson)
    {
        //确定存储路径
        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);
    }
    public T LoadData<T>(string fileName, JsonType type = JsonType.LitJson) where T : new()
    {
        //确定读取的路径
        //首先判断 读写数据文件夹中是否有我们想要的资源 如果有 就从中获取
        string path = Application.persistentDataPath + "/" + fileName + ".json";
        //如果不存在读写数据文件资源 就从默认数据文件夹中获取
        if (!File.Exists(path))
        {
            path = Application.streamingAssetsPath + "/" + fileName + ".json";
        }
        //如果默认文件夹中还没有 返回默认值
        if(!File.Exists(path))
        {
            Console.WriteLine("不存在文件资源");
            //返回默认值 因为传进来的也是默认值 保持输入输出不变
            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;
    }
}

3.LitJson字典的配置文件格式(字典格式:必须手动编写 JSON 配置文件 所以配置文件不推荐使用字典)

//数据结构
public class PlayerData
{
    // 使用字典保存玩家信息,键是玩家名字,值是 PlayerInfo
    public Dictionary<string, PlayerInfo> playerDict = new Dictionary<string, PlayerInfo>();
}
public class PlayerInfo
{
    public string playerName;
    public int level;
}

//配置文件格式
{
  "Alice": { "playerName": "Alice", "level": 5 },
  "Bob": { "playerName": "Bob", "level": 10 },
  "Charlie": { "playerName": "Charlie", "level": 8 }
}

4.Excel转Json(不用自己手动编写Json配置文件)

id    name       state   isNew
1     天下无双1   0       false
2     天下无双2   1       false
3     天下无双3   2       false
  • 转出后的内容(直接复制粘贴到配置文件可用)
[
{"id":1,"name":"天下无双1","state":0,"isNew":false},
{"id":2,"name":"天下无双2","state":1,"isNew":false},
{"id":3,"name":"天下无双3","state":2,"isNew":false}
]
posted @ 2025-12-08 16:33  高山仰止666  阅读(1)  评论(0)    收藏  举报