Unity游戏存档与读档

这篇具有很好参考价值的文章主要介绍了Unity游戏存档与读档。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

目前unity常见存档和读档有几种方式,也就是常见的存储数据的方式(注意存档和读档都是针对单机游戏而言的,角色信息,道具信息,关卡情况等)

Unity存档的方式大概分为这两大类

Unity游戏存档与读档

图片来源自siki学院

Unity游戏存档与读档

图片来源自siki学院

第一种:Player Prefs,这是一种键值对的形式,也就是说需要一个键和一个值,键就是用来存放值的,它是储存在注册表中的,由于注册表有限制,并且不安全数据容易被修改,因此常用改方法储存用户设置如音量大小,按键设置等。

使用方法也比较简单,因为是Unity自带的API所以可以直接在脚本中使用,在使用时也比较简单,该类提供了三种方法写入注册表,

分别是PlayerPrefs.SetInt(), PlayerPrefs.SetFloat(),PlayerPrefs.SetString();

void Start()
    {
        //这三个是写入注册表
        PlayerPrefs.SetInt("IsOn", 2);//"IsOn"是键,1是值,它整个是放在注册表中的
        PlayerPrefs.SetFloat("Voice", 0.5f);
        PlayerPrefs.SetString("Name", "张三");

        PlayerPrefs.Save(); //直接调用Set相关方法 只会把数据存到内存里

                            //当游戏结束时,unity会自动把数据存到硬盘中

                            //如果游戏在运行过程中崩溃,数据不会存储到硬盘中

                            //只要调用了该方法,数据就会立即保存。

        //这三个是获取
        //PlayerPrefs.GetInt("IsOn",0);这样的意思是获取键IsOn对应的值,如果IsOn键没有就返回0
        Debug.Log(PlayerPrefs.GetInt("IsOn"));
        Debug.Log(PlayerPrefs.GetFloat("Voice"));
        Debug.Log(PlayerPrefs.GetString("Name"));

//判断数据是否存在:
         if (PlayerPrefs.HasKey("IsOn"))
        {
            Debug.Log("数据存在");
        }
//删除指定键值对:
        PlayerPrefs.DeleteKey("year");
//删除所有存储信息:
        PlayerPrefs.DeleteAll();
    }

第二种:Binary(二进制):在存储较为复杂的数据,例如关卡信息,得分情况,剩余的子弹数量等公众信息时,可以将需要保存的信息都放在一个Save类中,这样就不用像写文档的形式分开存储(久而久之有可能会忘记数据对应的具体是什么),也比直接放在注册表中的功能要强大(毕竟注册表值存储三种数据类型),因此我们都会用存储类的对象的形式来储存数据(XML,Json同理)

既然要以对象的方式来存储数据,那么首先就需要创建一个新类专门用作储存数据,随后使用BinaryFormatter类将该类序列化后存入硬盘中

using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

[Serializable]//注意命名空间
public class Save //这是Save类
{
    //需要存储的具体信息根据自己的要求编写,这里只是举例
    internal int Score;//得分
    internal int PlayerLevel;//等级
    internal string PlayerSikll;//技能
    internal int PlayerHp;//血量
    internal int PlayerAp;//蓝量
}
using System.Collections;
using System.Collections.Generic;
using System.Runtime.Serialization.Formatters.Binary;//引入二进制转换器的命名空间
using UnityEngine;
using System.IO;

public class BinarySave : MonoBehaviour
{
    void SaveFun()//保存函数,也就是将Save对象转换为字节流的过程
    {
        Save BinarySaveObject = new Save();//声明Save对象,记录当前的游戏状态

        BinarySaveObject.PlayerAp = 100;//这里是直接对Save对象进行赋值,可以写一个函数然后返回值类型为Save类
        BinarySaveObject.PlayerHp = 5000;
        BinarySaveObject.PlayerLevel = 9;
        BinarySaveObject.PlayerSikll = "万雷诀";

        BinaryFormatter binaryFormatter = new BinaryFormatter();//这相当于一个二进制转换器

        FileStream fs = File.Create(Application.dataPath + "/StreamingFile" + "/BinaryTxt");//创建就一个文件流

        binaryFormatter.Serialize(fs, BinarySaveObject);//用二进制转换器的序列化方法把Save对象序列化,参数:创建的文件流和需要序列化的对象
        fs.Close();//关闭流
    }
    void LoadFun()//读档函数
    {
        if(File.Exists(Application.dataPath + "/StreamingFile" + "/BinaryTxt"))//这里最好还是判断文件是否存在
        {
            //二进制转换器
            BinaryFormatter bf = new BinaryFormatter();
            //打开一个文件流
            FileStream fs = File.Open(Application.dataPath + "/StreamingFile" + "/BinaryTxt", FileMode.Open);
            //用反序列化将文件流转换为对象
            Save save = (Save)bf.Deserialize(fs);
            fs.Close();

            Debug.Log(save.PlayerAp);//这里同样可以写函数返回值类型为Save类
            Debug.Log(save.PlayerHp);
            Debug.Log(save.PlayerLevel);
            Debug.Log(save.PlayerSikll);
        }
      
    }
    private void Start()
    {
        SaveFun();
        LoadFun();
    }
}

第三种:XML

学习XML之前先了解XML的大概格式,用一张例图应该就能明白

Unity游戏存档与读档
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Xml;//引入头文件
using UnityEngine;

public class XmlSave : MonoBehaviour
{
    void Save()//存档函数
    {
        Save XmlSaveObject = new Save();
        XmlSaveObject.PlayerAp = 100;//这里是直接对Save对象进行赋值,可以写一个函数然后返回值类型为Save类
        XmlSaveObject.PlayerHp = 5000;
        XmlSaveObject.PlayerLevel = 9;
        XmlSaveObject.PlayerSikll = "万雷诀";
        XmlSaveObject.Score = 45;

        string path = Application.dataPath + "/StreamingFile" + "/ByXml.json";//这是保存的路径

        //创建Xml文档,首先要有xml的文档才能操作
        XmlDocument xmlDoc = new XmlDocument();
        //创建根节点,也就是最外层的节点,这里就以Save对象为例
        XmlElement root = xmlDoc.CreateElement("Save");//用xml文档创建
        //设置根节点的值,对象名字为XmlSaveObject
        root.SetAttribute("name", "XmlSaveObject");

        //这里同样可以写成方法
        //1.创建子节点,2.并添加其内容,也就是对象中的各个字段并赋值,3.再将其添加到父节点中
        XmlElement PlayerAp = xmlDoc.CreateElement("PlayerAp");//这是创建子节点
        PlayerAp.InnerText = XmlSaveObject.PlayerAp.ToString();//这是为子节点添加内容
        root.AppendChild(PlayerAp);//这是将子节点添加进父节点中

        XmlElement PlayerHp = xmlDoc.CreateElement("PlayerHp");
        PlayerHp.InnerText = XmlSaveObject.PlayerHp.ToString();
        root.AppendChild(PlayerHp);

        XmlElement PlayerLevel = xmlDoc.CreateElement("PlayerLevel");
        PlayerLevel.InnerText = XmlSaveObject.PlayerLevel.ToString();
        root.AppendChild(PlayerLevel);

        XmlElement PlayerSikll = xmlDoc.CreateElement("PlayerSikll");
        PlayerSikll.InnerText = XmlSaveObject.PlayerSikll.ToString();
        root.AppendChild(PlayerSikll);

        XmlElement Score = xmlDoc.CreateElement("Score");
        Score.InnerText = XmlSaveObject.Score.ToString();
        root.AppendChild(Score);

        xmlDoc.AppendChild(root);//这是设置root为根
        xmlDoc.Save(path);//将xml文档保存在指定路径
    }
    void Load()//加载函数
    {
        string path = Application.dataPath + "/StreamingFile" + "/ByXml.json";
        if (File.Exists(path))//判断文件是否存在
        {
            Save XmlSaveObject = new Save();//创建对象
            //加载XML文档
            XmlDocument xmlDoc = new XmlDocument();
            xmlDoc.Load(path);//将硬盘中的xml文档加载到刚创建的xmlDoc中

            //通过节点名称来获取元素,结果为XmlNodeList类型
            XmlNodeList SaveObejct = xmlDoc.GetElementsByTagName("Save");
            //遍历所有的Save(这里因为就一个就遍历一次),并获得Save的子节点和子节点的InnerText
            if (SaveObejct.Count != 0)//判断是否为空
            {
                foreach(XmlNode tempsave in SaveObejct)//这里因为是获得了Save节点,想要里面的子节点就需要像下面这样
                {
                    XmlNode PlayerAp = tempsave.ChildNodes[0];//第一个子节点就是PlayerAp
                    XmlSaveObject.PlayerAp = XmlConvert.ToInt32(PlayerAp.InnerText);//将第一个子节点的内容赋值给XmlSaveObject对象

                    XmlNode PlayerHp = tempsave.ChildNodes[1];
                    XmlSaveObject.PlayerHp = XmlConvert.ToInt32(PlayerHp.InnerText);

                    XmlNode PlayerLevel = tempsave.ChildNodes[2];
                    XmlSaveObject.PlayerLevel = XmlConvert.ToInt32(PlayerLevel.InnerText);

                    XmlNode PlayerSikll = tempsave.ChildNodes[3];
                    XmlSaveObject.PlayerSikll = PlayerSikll.InnerText;

                    XmlNode Score = tempsave.ChildNodes[4];
                    XmlSaveObject.Score = XmlConvert.ToInt32(Score.InnerText);
                }
            }

            Debug.Log(XmlSaveObject.PlayerAp);
            Debug.Log(XmlSaveObject.PlayerHp);
            Debug.Log(XmlSaveObject.PlayerLevel);
            Debug.Log(XmlSaveObject.PlayerSikll);
            Debug.Log(XmlSaveObject.Score);
        }

    }

    private void Start()
    {
        Save();
        Load();
    }
}

第四种:Json:Json的具体讲解看另一篇,该例子使用的是LitJson文章来源地址https://www.toymoban.com/news/detail-467544.html

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using LitJson;
using System.IO;

public class JsonSave : MonoBehaviour
{
    void Save()//保存函数
    {
        Save JsonSaveObject = new Save();//声明Save对象,记录当前的游戏状态

        JsonSaveObject.PlayerAp = 100;//这里是直接对Save对象进行赋值,可以写一个函数然后返回值类型为Save类
        JsonSaveObject.PlayerHp = 5000;
        JsonSaveObject.PlayerLevel = 9;
        JsonSaveObject.PlayerSikll = "万雷诀";
        JsonSaveObject.Score = 45;

        //这里一定要注意需要字段为public权限,不然会导致转换不成功!!!
        string ObjectStr = JsonMapper.ToJson(JsonSaveObject);//将Save对象序列化为Json类型的字符串
        string path = Application.dataPath + "/StreamingFile" + "/ByJson.json";//这是保存的路径

        //对象被转换成了字符串,这个时候还是需要写进文件中,因此
        StreamWriter writer = new StreamWriter(path);//创建文件流
        writer.Write(ObjectStr);//写入
        writer.Close();//关闭文件流       
    }

    void Load()//加载函数
    {
        //最好做下判断文档是否存在,这里省略了
        string path = Application.dataPath + "/StreamingFile" + "/ByJson.json";//这是想打开的文件路径
        StreamReader reader = new StreamReader(path);//创建读取的文件流
        string ObjectStr = reader.ReadToEnd();//将文本文件中的内容全部读取到字符串中,(json格式其实就算字符串类型)
        reader.Close();//关闭流
        Save JsonSaveObject = JsonMapper.ToObject<Save>(ObjectStr);//将json格式转化成对象
        //注意这里其实也可以不用读取流的方法,可以直接将json文件放在Resources文件夹下,因为文本在unity中时TextAssets类型,可以直接通过Resources来加载json文件

        Debug.Log(JsonSaveObject.PlayerAp);
        Debug.Log(JsonSaveObject.PlayerHp);
        Debug.Log(JsonSaveObject.PlayerLevel);
        Debug.Log(JsonSaveObject.PlayerSikll);
        Debug.Log(JsonSaveObject.Score);

    }
    private void Start()
    {
        Save();
        Load();
    }
}

到了这里,关于Unity游戏存档与读档的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 简单的介绍几种在unity中对数据的存储和读档的方法!

    在unity中实现对游戏数据的存储和读档的方法主要有这么几种: 使用本地持久化类PlayerPrefs 使用二进制的方法序列化和反序列化(Serialize、Deserialize) 使用Json方法 使用XMl方法。 下面就通过一个简单的例子分别用这四种方法实现数据的存储和读档。 实现目标:    做一个简

    2024年02月07日
    浏览(36)
  • Unity简单本地存档系统

            本文主要记述一些我在研究Unity简单存档系统时的总结和见闻,纯属个人笔记。 前言涉及到一些本人自己的关于存档系统这一宽泛概念的总结,篇幅较长,如果不感兴趣请直接跳过到后面的脚本环节。 存档系统是绝大多数游戏不可或缺的内容(除了那些刻意为之的游

    2024年01月17日
    浏览(49)
  • 【Unity】C#存档与加密

    换工作了,这下是纯C#开发了,偏单机游戏,所以又要研究一下C#的存档做法。经过一阵时间的解决各种问题,现在已经稳定,需要的老铁可以参考一下。 https://github.com/protocolbuffers/protobuf/releases/ 下载需要的语言,解压后导入到自己的目录中。 ProtoContract 声明要序列化的类

    2024年02月05日
    浏览(32)
  • 【unity与android的交互】移动游戏发布更安心!Unity安卓平台打包相关的常见参数全详解

    👨‍💻个人主页 :@元宇宙-秩沅 👨‍💻 hallo 欢迎 点赞👍 收藏⭐ 留言📝 加关注✅! 👨‍💻 本文由 秩沅 原创 👨‍💻 收录于专栏 :Unity基础实战 首先需要切换到安卓平台 step1 :打包前的基础参数的设置 step2:包名的设置需要勾选,必须要去设置的内容 打包后进行测

    2024年04月17日
    浏览(75)
  • Unity背包系统与存档(附下载链接)

    下载地址: https://download.csdn.net/download/qq_58804985/88184776 视频演示: 功能: 拖动物品在背包中自由移动,当物品拖动到其他物品上时,和其交换位置.基于EPPlus的背包数据与位置保存 原理: 给定一个道具池表格与一个背包表格 道具池表格负责存储所有道具的信息 背包表格负责存储将玩

    2024年02月13日
    浏览(41)
  • 【unity小技巧】Unity 存储存档保存——PlayerPrefs、JsonUtility和MySQL数据库的使用

    游戏存档不言而喻,是游戏设计中的重要元素,可以提高游戏的可玩性,为玩家提供更多的自由和控制权。看完这篇文章就可以构建属于自己的存储系统了。 它是一个仅仅可以存储字符串、浮点数和整数值数据的类 保存

    2024年02月08日
    浏览(68)
  • 新手向 使用C#自带方法制作unity存档系统(无插件)

    纯原创,自制 本人还是个在校的高中生,能力不精如果有漏洞欢迎指出 先放出我们示范项目的样子 演示项目工程文件下载 后面会在B站发详细的视频教程(所以文章之后肯会改) 嫌麻烦的直接复制到项目里就可以用哦 (全部的SaveSystem源码最后放出方便大家复制) 可以存储

    2024年02月10日
    浏览(53)
  • 【Unity游戏开发中的常见问题第二卷】AnyState小坑导致动画卡在第一帧

    在使用 Unity 自带的 Animator 时偶然出现的问题,有一个动画是通过 Any State 传递的,然后碰到了一直卡在第一帧的情况,其实是一个设置问题,需要把 Can Transition To Self ,可能也有其他原因导致类似问题的发生,不过感觉这应该是新手常碰的问题了~ 如果你不禁用传输到自身

    2024年02月16日
    浏览(56)
  • c++游戏小技巧12:输入输出流(存读档超全版)

    目录 1.前言 2.输入/输出概念 3.流的概念 4.正文 1.标准I/O流 1.get()函数  2.getline()函数 3.read()函数  4.ignore()函数 5.gcount()函数 6.peek()函数 7.putback()函数 8.istream集合栗子 9.put()函数 10.write()函数 11.ostream集合栗子 2.文件I/O流 1.流的关闭 2.缓冲区类型 3.设置缓冲区属性 4.缓冲区清空

    2024年02月13日
    浏览(44)
  • 幻兽帕鲁转移/迁移游戏存档之后,无法迁移角色存档,进入游戏需要重新建角色问题(已解决),服务器到服务器之间的存档转移

    很多朋友在迁移幻兽帕鲁游戏存档到服务器的时候,可能会遇到一个问题,就是迁移完成后,进入到游戏会发现又需要从头开始,重新新建角色。 其实这个问题也很好解决,因为Palworld服务端有两种,一种是有APPID,还有一种是没有APPID。   如果迁移的前后服务器版本不一致

    2024年02月20日
    浏览(46)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包