谈谈关于如何在Unity中将数据转为json文件来进行存储与读取,使用的都是JsonUtility中的方法,非常的便捷
新建SaveSystem类
新建一个SaveSystem类来方便方法的调用
using System;
using System.IO;
using UnityEngine;
public class SaveSystem : MonoBehaviour
{
}
数据写入json文件并存储
在SaveSystem类下写存储方法,简单来说,先通过ToJson方法将数据转换为json格式的文本,在将文本写入到文件中。其中perisistentDataPath是一个根据不同平台对应的不同路径(例如windows和android的路径并不相同)
/// <summary>
/// 将数据存入json文件
/// </summary>
/// <param name="fileName">文件名及路径</param>
/// <param name="data">数据</param>
public static void SaveToJson(string fileName, object data)
{
var json = JsonUtility.ToJson(data);
var path = Path.Combine(Application.persistentDataPath, fileName) + ".json";
try
{
File.WriteAllText(path, json);
#if UNITY_EDITOR
Debug.Log($"success to save data to {path}");
#endif
}
catch (SystemException)
{
#if UNITY_EDITOR
Debug.Log($"fail to save data to {path}");
#endif
}
}
方法的调用示例
假设我们要存出一个Student类(需要注意只有能够序列化的数据类型能够被存储,类型不受支持的字段以及私有(private)字段或使用 NonSerialized 属性标记的字段会被忽略)
public class Student
{
public string name;
public int id;
}
调用上面的方法将其转换为json文件并进行存储
var student = new Student();
student.name = "Mike";
student.id = 12;
SaveSystem.SaveToJson("student01", student);
这样就可以进行存储了,windows下的json文件路径为C:\User\UserName(你自己的用户名)\AppData\LocalLow\DefaultCompany\project(项目名称)\
数据读取与实例化(一般的)
读取文件其实也非常简单,只需要使用FromJson方法将json文本转换为对应类型的object就可以了
/// <summary>
/// 将数据通过json文件读取
/// </summary>
/// <param name="fileName">文件名及路径</param>
/// <typeparam name="T">读取数据类型</typeparam>
/// <returns></returns>
public static T LoadFromJson<T>(string fileName)
{
var path = Path.Combine(Application.persistentDataPath, fileName) + ".json";
try
{
var json = File.ReadAllText(path);
var data = JsonUtility.FromJson<T>(json);
#if UNITY_EDITOR
Debug.Log($"success to load data from {path}");
#endif
return data;
}
catch (SystemException)
{
#if UNITY_EDITOR
Debug.Log($"fail to load data from {path}");
#endif
return default;
}
}
需要注意的是,FromJson方法只支持普通类和结构;不支持派生自 UnityEngine.Object 的类(如 MonoBehaviour 或 ScriptableObject)。具体请查看官方文档中的JsonUtility-FromJson - Unity 脚本 API
方法的调用,还是以Student类举例
var student = SaveSystem.LoadFromJson<Student>("student01")
点击查看SaveSystem类的完整代码
using System;
using System.IO;
using UnityEngine;
public class SaveSystem : MonoBehaviour
{
/// <summary>
/// 将数据存入json文件
/// </summary>
/// <param name="fileName">文件名及路径</param>
/// <param name="data">数据</param>
public static void SaveToJson(string fileName, object data)
{
var json = JsonUtility.ToJson(data);
var path = Path.Combine(Application.persistentDataPath, fileName) + ".json";
try
{
File.WriteAllText(path, json);
#if UNITY_EDITOR
Debug.Log($"success to save data to {path}");
#endif
}
catch (SystemException)
{
#if UNITY_EDITOR
Debug.Log($"fail to save data to {path}");
#endif
}
}
/// <summary>
/// 将数据通过json文件读取
/// </summary>
/// <param name="fileName">文件名及路径</param>
/// <typeparam name="T">读取数据类型</typeparam>
/// <returns></returns>
public static T LoadFromJson<T>(string fileName)
{
var path = Path.Combine(Application.persistentDataPath, fileName) + ".json";
try
{
var json = File.ReadAllText(path);
var data = JsonUtility.FromJson<T>(json);
#if UNITY_EDITOR
Debug.Log($"success to load data from {path}");
#endif
return data;
}
catch (SystemException)
{
#if UNITY_EDITOR
Debug.Log($"fail to load data from {path}");
#endif
return default;
}
}
}
ScriptableObject类的读取
由于ScriptableObject可以很方便地在Unity中进行编辑,并且作为仅存储数据的用途非常的轻量化,所以也特别地讲一下
假设我们有一个Teacher类继承了ScriptableObject
[Serializable][CreateAssetMenu(menuName = "Teacher")]
public class Teacher : ScriptableObject
{
public string name;
public int id;
}
我们在代码中创建了实例并且对其进行了存储
var teacher = ScriptableObject.CreateInstance<Teacher>();
teacher.name = "Ben";
teacher.id = 0;
SaveSystem.SaveToJson("teacher01", teacher);
接下来我们需要读取数据,首先需要在Teacher类下实现LoadFromDisk方法,与SaveSystem中的LoadFromJson方法不同的点在于,我们需要使用的方法不是FromJson而是FromJsonOverwrite
public bool LoadFromDisk(string fileName)
{
var path = Path.Combine(Application.persistentDataPath, fileName) + ".json";
try
{
var json = File.ReadAllText(path);
JsonUtility.FromJsonOverwrite(json, this);
#if UNITY_EDITOR
Debug.Log($"success to load data from {path}");
#endif
return true;
}
catch (SystemException)
{
#if UNITY_EDITOR
Debug.Log($"fail to load data from {path}");
#endif
return false;
}
}
然后再创建示例并调用该方法,即可读取数据
var teacher = ScriptableObject.CreateInstance<Teacher>();
teacher.LoadFromDisk("teacher01");