在Unity里寫一個簡單的存檔系統



新手上路,想在Unity里做一個簡單的存檔系統,查閱網上較多資料后完成,以此記錄。
基於 Newtonsoft.Json 類庫。

1. 在Unity項目導入Newtonsoft.Json.dll

  1. 下載Newtonsoft.Json.dll,網上資源很多,這里就不放出了。
  2. 在Unity項目的Assets文件夾下,新建一個名叫 Plugins 的文件夾,將dll放進去,即完成導入。在打包時(PC),在文件夾中的dll文件也會打包到Managed文件夾中。

2.對存檔簡單的認識

個人沒有去深入了解Json的具體語法,但個人理解上的話,大概流程就是:

存入數據:

  1. 將數據對象轉化成用Json格式編寫的字符串(也就是序列化)。
  2. 將此字符串寫入文件中。
    取出數據:
  3. 將文件中的Json格式的字符串讀出。
  4. 將取出的字符串轉化為數據對象(也就是反序列化)。

其中,Newtonsoft.Json 類庫中就有1和4用於轉化的API。

要注意的是,Json不能直接轉化Unity中某些數據類型(比如Vector2/3),要對他們做一定的轉化。

3.編寫代碼

有了2中的思路,就已經可以着手去寫了。
主要用到的API:

  1. 各種文件IO
  2. public static T JsonConvert.DeserializeObject (string value),該函數能將Json格式字符串轉化為數據對象,也就是反序列化。
  3. 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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM