新手上路,想在Unity里做一个简单的存档系统,查阅网上较多资料后完成,以此记录。
基于 Newtonsoft.Json 类库。
1. 在Unity项目导入Newtonsoft.Json.dll
- 下载Newtonsoft.Json.dll,网上资源很多,这里就不放出了。
- 在Unity项目的Assets文件夹下,新建一个名叫 Plugins 的文件夹,将dll放进去,即完成导入。在打包时(PC),在文件夹中的dll文件也会打包到Managed文件夹中。
2.对存档简单的认识
个人没有去深入了解Json的具体语法,但个人理解上的话,大概流程就是:
存入数据:
- 将数据对象转化成用Json格式编写的字符串(也就是序列化)。
- 将此字符串写入文件中。
取出数据: - 将文件中的Json格式的字符串读出。
- 将取出的字符串转化为数据对象(也就是反序列化)。
其中,Newtonsoft.Json 类库中就有1和4用于转化的API。
要注意的是,Json不能直接转化Unity中某些数据类型(比如Vector2/3),要对他们做一定的转化。
3.编写代码
有了2中的思路,就已经可以着手去写了。
主要用到的API:
- 各种文件IO
- public static T JsonConvert.DeserializeObject
(string value),该函数能将Json格式字符串转化为数据对象,也就是反序列化。 - public static string JsonConvert.SerializeObject(object value),该函数能将一个数据对象转化为Json格式的字符串,也就是序列化。
别忘记用库的东西要 using Newtonsoft.Json;
4.具体代码
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Newtonsoft.Json;
namespace CustomSaveLoadSystem
{
public class SaveAndLoadSystem
{
/// <summary>
/// 默认保存的相对路径
/// </summary>
private static string savePath = "SaveData";
/// <summary>
/// 报存数据
/// </summary>
/// <param name="saveObject">要保存的对象</param>
/// <param name="name">要存入的文件名</param>
public static void Save(object saveObject, string name = "save")
{
//创建文件夹
string folderPath = System.IO.Path.Combine(Application.dataPath, savePath); //文件夹路径
System.IO.Directory.CreateDirectory(folderPath);
//创建一个空白文件
string fileName = name + ".json"; //文件名
string filePath = System.IO.Path.Combine(folderPath, fileName); //文件路径
System.IO.File.Create(filePath).Dispose();
//序列化
string str_json = JsonConvert.SerializeObject(saveObject);
//写入文件
System.IO.StreamWriter sw = new System.IO.StreamWriter(filePath);
sw.Write(str_json);
sw.Close();
//确认保存
if (System.IO.File.Exists(filePath))
Debug.Log("保存成功");
else
Debug.Log("保存失败");
}
/// <summary>
/// 取出存储的数据
/// </summary>
/// <typeparam name="T">取出类型</typeparam>
/// <param name="loadObject">将取出数据放入</param>
/// <param name="name">文件名</param>
/// <returns>返回是否能够读取成功</returns>
public static bool Load<T>(out T loadObject, string name = "save")
{
//找出文件路径
string folderPath = System.IO.Path.Combine(Application.dataPath, savePath); //文件夹路径
string fileName = name + ".json"; //文件名
string filePath = System.IO.Path.Combine(folderPath, fileName); //文件路径
loadObject = default;
if (System.IO.File.Exists(filePath))
{
//读取文件
System.IO.StreamReader sr = new System.IO.StreamReader(filePath);
string str_json = sr.ReadToEnd();
sr.Close();
//反序列化
loadObject = JsonConvert.DeserializeObject<T>(str_json);
Debug.Log("成功读取");
return true;
}
Debug.Log("读取失败");
return false;
}
}
}
5.对个别数据类型的处理
由于不能直接对Vector2,Vector3等类型直接序列化,所以要对这些类型做一些处理。
我新建了一个结构体,专门用于Vector2的转化(其他类型同理):
public struct SerializeableVector2
{
public SerializeableVector2(Vector2 vec)
{
this.x = vec.x;
this.y = vec.y;
}
public double x;
public double y;
public Vector2 ToVector2()
{
return new Vector2((float)x, (float)y);
}
}
6.其他要注意的点(踩了的坑)
打包时,要注意API版本,选择 .NET 4.x