在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

猜你喜欢

转载自www.cnblogs.com/yasoudream/p/12346316.html