Unity中常用的游戏存档/读档技术

Unity中常用的游戏存档/读档技术

1.PlayerPrefs:是Unity提供的一个用于本地持久化保存与读取的类,是以键值对的形式将数据写入到注册表中,并且可以提供方法来按照键来取出对应的值应用到游戏中,适用于保存较为简单的游戏数据。对应的方法如下:
PlayerPrefs.SetInt(string key,int value);//保存int型的值
PlayerPrefs.GetInt(string key);//获取保存的int型值。
PlayerPrefs.SetFloat(string key,float value);//保存float型的值
PlayerPrefs.GetFloat(string key);//获取保存的float型值。
PlayerPrefs.SetString(string key,string value);//保存string型的值
PlayerPrefs.GetString(string key);//获取保存的string型值。
当去获取的值在注册表中并不存在的时候,会返回默认值!
除了以上的方法以外,还提供了PlayerPrefs.DeleteKey(string key)来删除对应的键值,还有PlayerPrefs.DeleteAll();来删除所有的键值。

应用场景:
  以下的三种方式是我应用在我的打地鼠游戏中的存取方式,主要用来保存地鼠出现的位置(0-8)以及地鼠的类型(0-3),以及击打的次数和得分等等信息。

2.二进制数据存取方法:将游戏对象序列化为二进制数据流进行传输和存储,当需要使用的时候将数据流反序列化为游戏对象即可。在对游戏对象进行序列化的时候,需要在类前声明[System.Serializable]证明是可序列化的。执行存档以后会在指定路径下生成一个txt文件,但是由于是数据流,可读性很差。主要的核心代码如下:
二进制存档:

    ///二进制存档 
    private void SaveByBin()
    {
    
    
        Save save = GetSaveInfo();//先将需要存档的游戏信息读取过来并保存起来
        BinaryFormatter bf = new BinaryFormatter();//创建一个二进制格式化程序
        FileStream fileStream = File.Create(Application.dataPath + "/StreamingFiles" + "/Bin.txt");//创建一个文件流
        bf.Serialize(fileStream, save);//利用二进制格式化程序的序列化方法来序列化save对象,参数:创建的文件流和需要序列化的对象
        fileStream.Close();  //关闭流
        if (File.Exists(Application.dataPath + "/StreamingFiles" + "/Bin.txt"))
        {
    
    
            ShowMessage("保存成功!");
        }
    }

二进制存档:

    private void LoadByBin()//加载游戏就是一个反序列化的过程
    {
    
    
        if (File.Exists(Application.dataPath + "/StreamingFiles" + "/Bin.txt"))
        {
    
    
            BinaryFormatter bf = new BinaryFormatter();//创建一个二进制格式化程序
            FileStream fileStream = File.Open(Application.dataPath + "/StreamingFiles" + "/Bin.txt", FileMode.Open);//打开数据流
            Save save = (Save)bf.Deserialize(fileStream);//调用二进制格式化程序中的反序列化方法,将数据流反序列化为save对象并进行保存
            fileStream.Close();//关闭文件流
            SetGame(save);//反序列化之后得到的对象再传入到SetGame()中,设置游戏数据
            ShowMessage("");
        }
        else
        {
    
    
            ShowMessage("文件不存在,加载失败!!!");
            Debug.Log("加载失败!!");
        }
    }

效果图如下:
二进制存储图片

3.Json数据存取:Json是将游戏对象转换成字符串形式并且写入到指定路径下的json文档中来进行存储的,当需要的时候又将字符串转换成游戏对象。字符串和游戏对象之间的转换需要导入并且引用库文件using LitJson;,同时也对文件的读写进行了操作,所以也要引入命名空间using System.IO;,最后生成的文件可读性比二进制的高
具体实现代码如下:

Json存档:

    private void SaveByJson()
    {
    
    
        //using LitJson;下载导入并引入库LitJson
        Save save = GetSaveInfo();//依旧使用对象来接收需要保存的游戏数据
        string filePath = Application.dataPath + "/StreamingFiles" + "/Json.json";//创建路径
        string saveJsonStr = JsonMapper.ToJson(save);//利用JsonMapper将save对象转换成Json格式的字符串
        //将字符串写入到文件中
        //创建一个StreamWriter,调用其中的方法来将字符串写入到文件中
        StreamWriter sw = new StreamWriter(filePath);
        sw.Write(saveJsonStr);//写入到创建好的文件中,调用文件的读写函数需要引入命名空间using System.IO;
        sw.Close();//关闭StreamWriter
        if (File.Exists(Application.dataPath + "/StreamingFiles" + "/Json.json"))
        {
    
    
            ShowMessage("Json保存成功!!!");
        }
        else
        {
    
    
            ShowMessage("Json文件保存失败!!");
        }
    }

Json读档:

    private void LoadByJson()
    {
    
    
        string filePath = Application.dataPath + "/StreamingFiles" + "/Json.json";//首先先获得保存好的Json文件的路径
        if (File.Exists(filePath))//有文件才开始读档
        {
    
    
            StreamReader streamReader = new StreamReader(filePath);//创建一个读取的StreamWrite用来读取文档的内容
            string jsonStr = streamReader.ReadToEnd();//将文件流读取到末尾用字符串进行存储
            streamReader.Close();//读取完毕之后就关闭流
            Save save = JsonMapper.ToObject<Save>(jsonStr);//在读取完毕之后就调用JsonMapper中的函数叫读取的字符串转换成对象
            SetGame(save);//将获得的对象传入设置游戏的函数
            ShowMessage("");
        }
        else
        {
    
    
            ShowMessage("文件不存在,读档失败!");
        }

    }

效果图如下:
Json效果图

4.XML数据存取:XML这种存储方式是一种节点存储方式,其格式很像html,将得到的对象数据分解存到不同的节点的innerText属性中,然后再设置每一个节点的之间的层级关系,最后存入到文件中,文件的可读性非常好。具体的操作流程如下:
1.引入Using System.XML命名空间,利用XmlDocument创建Xml文档。
2.创建节点,并根据获取的游戏对象的值来设置节点的innerText的值。
3.设置节点之间的层级关系,然后保存文件即可。
取出文件时反之即可!
具体实现代码如下:
XML存档:

    private void SaveByXml()
    {
    
    
        Save save = GetSaveInfo();//先获取需要保存的对象
        string filePath = Application.dataPath + "/StreamingFiles" + "/XML.txt";//设置文件保存的路径,并且引入命名空间Using System.XML
        XmlDocument xmlDoc = new XmlDocument();//创建XML文档
        //创建根节点,即最上层的节点
        XmlElement root = xmlDoc.CreateElement("save");
        //设置根节点中的值
        root.SetAttribute("name", "saveFileXML");

        //通过target中的怪物的位置和种类来定义和设置文档中的元素,进行规范存储
        XmlElement Target;
        XmlElement TargetPosition;
        XmlElement MonsterType;

        for (int i = 0; i < save.monstersPositionList.Count; i++)
        {
    
    
            //创建节点
            Target = xmlDoc.CreateElement("Target");
            TargetPosition = xmlDoc.CreateElement("TargetPosition");
            MonsterType = xmlDoc.CreateElement("MonsterType");

            //设置节点中的内容,并且设置好父节点 层级关系为root--Target-(TargetPosition,MonsterType);
            TargetPosition.InnerText = save.monstersPositionList[i].ToString();//设置位置的文本值
            Target.AppendChild(TargetPosition);//设置根节点关系,TargetPosition是Target的子孩子
            MonsterType.InnerText = save.monstersTypeList[i].ToString();//设置怪物类型的值
            Target.AppendChild(MonsterType);//设置根节点的关系,MonsterType是Target的子孩子
            //将target也设置为根节点的子孩子
            root.AppendChild(Target);
        }
        //设置设计数量和得分,为root的子孩子
        XmlElement shootNum = xmlDoc.CreateElement("ShootNum");
        shootNum.InnerText = save.shootNum.ToString();
        root.AppendChild(shootNum);
        XmlElement score = xmlDoc.CreateElement("Score");
        score.InnerText = save.score.ToString();
        root.AppendChild(score);
        //将root节点设置为文档的初始节点然后将文档保存到指定的路径之中
        xmlDoc.AppendChild(root);
        xmlDoc.Save(filePath);//将文档保存到指定的路径之中
        if (File.Exists(Application.dataPath + "/StreamingFiles" + "/XML.txt"))
        {
    
    
            ShowMessage("XML保存成功!!!");
        }
    }

XML读档:

扫描二维码关注公众号,回复: 15094259 查看本文章
  private void LoadByXml()
    {
    
    
        string filePath = Application.dataPath + "/StreamingFiles" + "/XML.txt";
        if (File.Exists(filePath))
        {
    
    
            Save save = new Save();//创建save对象,用来返回
            XmlDocument xmlDoc = new XmlDocument();//创建文本
            xmlDoc.Load(filePath);//根据路径读取内容到文本之中
            //通过节点来获取元素,结果为XMLLoadList类型
            XmlNodeList Targets = xmlDoc.GetElementsByTagName("Target");//根据名字为Target的元素加入到节点列表中
            //遍历所有的Target节点,并且获得它的子孩子和子孩子的InnerText
            if (Targets.Count!=0)//假如至少有一个的话,表示文档中怪物至少有一个的话,那么就遍历Targets中的所有target
            {
    
    
                foreach (XmlNode Target in Targets)
                {
    
    
                    //存放位置信息
                    XmlNode TargetPosition = Target.ChildNodes[0];//节点的第一个子孩子为位置,第二个子孩子为怪物的类型
                    save.monstersPositionList.Add(int.Parse(TargetPosition.InnerText));//在列表中就存入了位置信息
                    //存放怪物的类型
                    XmlNode MonsterType = Target.ChildNodes[1];
                    save.monstersTypeList.Add(int.Parse(MonsterType.InnerText));  
                }
            }
            //设置射击数和得分
            save.shootNum =int.Parse( xmlDoc.GetElementsByTagName("ShootNum")[0].InnerText);
            save.score = int.Parse(xmlDoc.GetElementsByTagName("Score")[0].InnerText);
            SetGame(save);
        }
        else
        {
    
    
            ShowMessage("XML文件不存在,加载失败!!!");
        }
    }

效果图如下:
XML文件
总结:
  几种存取方式都有自己的独特点。如果有不足之处希望各位大佬评论指正!

猜你喜欢

转载自blog.csdn.net/Wu_0526/article/details/116203890