抱歉,您的浏览器无法访问本站
本页面需要浏览器支持(启用)JavaScript
了解详情 >

我看了看手上的牌,明白自己无牌可出

谈谈关于如何在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");

评论