【Unity】简易游戏存档

前言

游戏存档的功能和重要性不需要过多叙述,实现的方法也很多样。

对于Unity来讲,最简单的就是用PlayerPrefs来搞。但是就因为简单,所以能实现的功能也比较少。目前PlayerPrefs存些Int、String显然是不够的。

所以推荐一个C#自带的序列化来做存档,简单易用,功能全面,而且简单,会一点C#就能会。

 

原理

用 FileStream 和 BinaryFormatter 来将一个C#的类存成持久文件。

核心代码很简单,如下:

BinaryFormatter formatter = new BinaryFormatter();
FileStream saveFile = File.Create(savePath);
formatter.Serialize(saveFile, saveObject);
saveFile.Close();

 

实现

1、准备工作

首先要给你的存档们准备一个文件夹来存放你的存档,如果没有的话就创建一个,然后需要给你打算保存的类指定一个文件名。

//Unity的话推荐 Application.persistentDataPath

//这里写的是一个获取文件路径+创建存档文件夹二合一功能的方法;


        /// <summary>
        /// 获取游戏存档的文件夹路径;
        /// </summary>
        static string GetGameSaveFilePath(string name)
        {
            string PersistantPath=Application.persistentDataPath;
            string Dir = PersistantPath + "/Save";
            if (!Directory.Exists(Dir))
            {
                Directory.CreateDirectory(Dir);
            }
            return Dir + "/" + name + ".Save";
        }  

这里返回具体文件的时候,我给加了个后缀名 .Save,其实这个是随便加得。愿意加什么后缀就加什么后缀,自定义的,可以当成自己的存档标记(最好不要与现有的应用程序冲突)。

这样就把存档定在一个文件夹下面了,叫做XXX.Save的文件。这就是我们预计存的文件名。

 

2、文件保存

先上代码:

        public static void Save(string fileName, object saveObject)
        {
            //获取文件路径,有两个地方可以选择
            string savePath = GetGameSaveFilePath(fileName);

            Logger.Log("保存文件:" + savePath);
            BinaryFormatter formatter = new BinaryFormatter();
            FileStream saveFile = File.Create(savePath);
            formatter.Serialize(saveFile, saveObject);
            saveFile.Close();
        }

这里的saveObject是随便你自己写的什么类都可以,没有什么特定的要求。

一般没有什么报错就算是存下来了~~

 

3、文件读取

一般来讲读取的时候是一股脑都读取的,最后选择其中一个来进行游戏。

下面这个方法是获取之前路径下的所有文件,以FileInfo的形式返回。

        /// <summary>
        /// 获取存档路径下的所有.Save文件;
        /// </summary>
        /// <returns></returns>
        static FileInfo[] GetAllSaveFiles()
        {
            string Dir = Application.persistentDataPath + "/Save";
            if (!Directory.Exists(Dir))
            {
                return null;
            }
            DirectoryInfo direct = new DirectoryInfo(Dir);
            return direct.GetFiles("*.Save", SearchOption.AllDirectories);
        }

这下面这个方法是加载一个具体的文件:

        public static object Load(string fileName)
        {
            string savePath = GetGameSaveFilePath(fileName);

            Logger.Log("读取文件:" + savePath);
            BinaryFormatter formatter = new BinaryFormatter();
            if (File.Exists(savePath))
            {
                FileStream saveFile = File.Open(savePath, FileMode.Open, FileAccess.Read, FileShare.Read);
                object returnObject = formatter.Deserialize(saveFile);
                saveFile.Close();
                return returnObject;
            }
            else
            {
                Logger.LogWarning("文件不存在:   " + savePath);
                return null;
            }
        }

这样加载完只有就有是一个Object了,可以用 Object as 的方法转成自己定义的类。

 

4、存档的删除

用C#的删除就可以,指定一个文件路径,直接删就完事了。

        /// <summary>
        /// 删除;
        /// </summary>
        /// <param name="fileName"></param>
        public static void Delete(string fileName)
        {
            string curPath = GetGameSaveFilePath(fileName);
            Logger.Log("删除文件:" + curPath);
            if (File.Exists(curPath))
            {
                File.Delete(curPath);
            }
        }

 

备注

1、存储的限制

用来存储的类中所有的属性都得是可存储的(似乎是废话),否则会报错。理论上你在类里引用别的类,就需要在被引用的类中加上     [System.Serializable]  标记。如果类中有些什么东西不能存反正会报错,大家看着报错自己改改就好了。

 

2、如何不保存

如果类中的某些属性/字段不需要保存,就在这个字段上加上 [System.NonSerialized] 。

所以如果使用了一些字段又不需要保存的话,可以加上这个Tag,然后就可以减少一下文件大小。

 

 

推荐一个SaveMangaer的写法的博客:

https://blog.csdn.net/q568360447/article/details/62273337?depth_1-utm_source=distribute.pc_relevant_right.none-task-blog-OPENSEARCH-1&utm_source=distribute.pc_relevant_right.none-task-blog-OPENSEARCH-1

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值