新手上路,想在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