此文章基于Unity针对Json的数据存储以及读取进行基础描述。
【注意】首先需要引入外部dll文件,这里使用的是Litjson。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using LitJson;
using System.IO;
using System.Text.RegularExpressions;
public class JsonExManager : SingletonTool<JsonExManager>
{
/// <summary>
/// 创建json实例解析数据
/// </summary>
/// <typeparam name="T">实例泛型</typeparam>
/// <param name="path">json文件路径</param>
/// <returns></returns>
public T JsonEx<T>(string path) where T : class, new()
{
string jsonStr = File.ReadAllText(path);
T root = JsonMapper.ToObject<T>(jsonStr);
return root;
}
/// <summary>
/// jsonData解析数据
/// </summary>
/// <param name="path">json文件路径</param>
/// <returns></returns>
public JsonData JsonEx(string path)
{
string jsonStr = File.ReadAllText(path);
JsonData root = JsonMapper.ToObject(jsonStr);
return root;
}
/// <summary>
/// 更新json数据
/// </summary>
/// <param name="path">json文件路径</param>
/// <param name="jsonData">JsonData实例</param>
public void UpdateJsonData(string path, JsonData jsonData)
{
//创建用来表示转换json编码的正则表达式对象
Regex reg = new Regex(@"(?i)\\[uU]([0-9a-f]{4})");
//查找指定JsonData对象中的json编码进行替换
var mesg = reg.Replace(jsonData.ToJson(), delegate (Match m)
{
return ((char)System.Convert.ToInt32(m.Groups[1].Value, 16)).ToString();
});
//写入修改后的文件
FileStream file = new FileStream(path, FileMode.Create);
byte[] bts = System.Text.Encoding.UTF8.GetBytes(mesg);
file.Write(bts, 0, bts.Length);
file.Close();
}
}
此段代码是对Litjson解析以及修改Json文件代码的简单封装(继承的SingletonTool单例类可以自行创建)。
读取Json文件的内容大致分为两个模式,第一种是针对Json文件的结构创建对应的C#脚本实例,对于数据的结构清晰简洁重复性较高的工程可以使用创建实例的方式,对于数据的结构杂乱繁多的情形建议使用第二种方式,即将数据集中存储在json解析出的数组里,在数组里进行索引获取,这种形式需要注意一点就是json的文件结构要有良好的可读性。
因为网上有很多在线将json文件转成对应脚本实例的工具所以手动实现是很费力的方法,在这里直接描述第二种方式,用数组存储数据进行读取,解析的目标Json文件如下:
{
"FishConfig": {
"乌龟": {
"Name": "乌龟",
"Hp": "50",
"Exp": "30",
"Gold": "30",
"Max Num": "2",
"Max Speed": "15"
},
"刺猬鱼": {
"Name": "刺尾鱼",
"Hp": "100",
"Exp": "130",
"Gold": "80",
"Max Num": "2",
"Max Speed": "30"
},
"大眼睛鱼": {
"Name": "大眼睛鱼",
"Hp": "153",
"Exp": "182",
"Gold": "80",
"Max Num": "3",
"Max Speed": "25"
}
}
解析的对应脚本如下:
public void SetFishData()
{
string path = Application.dataPath + "/StreamingAssets/Json/FishConfig.json";
JsonData jsonData = JsonExManager.Instance.JsonEx(path);
fishDataList.Add(new FishData(
jsonData["FishConfig"][0]["Name"].ToString(),
Convert.ToInt32(jsonData["FishConfig"][0]["Hp"].ToString()),
Convert.ToInt32(jsonData["FishConfig"][0]["Exp"].ToString()),
Convert.ToInt32(jsonData["FishConfig"][0]["Gold"].ToString()),
Convert.ToInt32(jsonData["FishConfig"][0]["Max Num"].ToString()),
Convert.ToInt32(jsonData["FishConfig"][0]["Max Speed"].ToString())
));
fishDataList.Add(new FishData(
jsonData["FishConfig"][1]["Name"].ToString(),
Convert.ToInt32(jsonData["FishConfig"][1]["Hp"].ToString()),
Convert.ToInt32(jsonData["FishConfig"][1]["Exp"].ToString()),
Convert.ToInt32(jsonData["FishConfig"][1]["Gold"].ToString()),
Convert.ToInt32(jsonData["FishConfig"][1]["Max Num"].ToString()),
Convert.ToInt32(jsonData["FishConfig"][1]["Max Speed"].ToString())
));
fishDataList.Add(new FishData(
jsonData["FishConfig"][2]["Name"].ToString(),
Convert.ToInt32(jsonData["FishConfig"][2]["Hp"].ToString()),
Convert.ToInt32(jsonData["FishConfig"][2]["Exp"].ToString()),
Convert.ToInt32(jsonData["FishConfig"][2]["Gold"].ToString()),
Convert.ToInt32(jsonData["FishConfig"][2]["Max Num"].ToString()),
Convert.ToInt32(jsonData["FishConfig"][2]["Max Speed"].ToString())
));
}
获取到json的文件路径后直接通过封装的方法进行文件的解析,最后获得数组形式的数据对象,在数组中对json里的数据进行读取,这里可以采用索引的形式进行读取,也可以采用数据名称的形式进行直接获取,按照自己工程的内容进行选取即可。由于数据量较多,这里构造了FishData结构体,并用fishDataList集合对结构体进行存储,然后将集合内的数据应用到游戏的实际参数上即可。
数据存储好之后会涉及到更改json数据后保存修改后的数据的问题,保存json文件时,将需要进行更改的数据复制给对应的json解析后的数组里,以下端代码为例,先将json文件解析,将解析后的json数组里的数据进行赋值更改,最后调用封装脚本里更新保存json数据的方法即可。
public void SaveJsonData(string path)
{
SetFishData();
SetBulletData();
JsonData jsonData = JsonExManager.Instance.JsonEx(path);
jsonData["GameConfig"]["MainData"]["Lv"] = lv.ToString();
jsonData["GameConfig"]["MainData"]["Gold"] = gold.ToString();
jsonData["GameConfig"]["MainData"]["Exp"] = exp.ToString();
jsonData["GameConfig"]["MainData"]["IsPlay"] = isPlayAudio.ToString();
for (int i = 0; i < jsonData["GameConfig"]["CostData"].Count; i++)
{
costList.Add(
Convert.ToInt32(jsonData["GameConfig"]["CostData"][i].ToString())
);
}
for (int i = 0; i < jsonData["GameConfig"]["LevelData"].Count; i++)
{
lvList.Add(
jsonData["GameConfig"]["LevelData"][i].ToString()
);
}
JsonExManager.Instance.UpdateJsonData(path, jsonData);
}
【注意】json文件的编码格式不正确会导致解析出的中文字符乱码,所以建议使用Notepad++或其他工具将文件进行转码(转成对应平台支持的编码格式,大多数格式为utf-8 无 bom编码格式)