【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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章