Unity 常用的几种存档读档方式

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

一、PlayerPrefs:数据持久化方案

常见的方法如下:

// PlayerPrefs读取
PlayerPrefs.GetInt("123asd");       // 如果我们之前没有过这个键,那么返回默认值就是0
PlayerPrefs.GetFloat("asd");        // 如果我们之前没有过这个键,那么返回默认值就是0
PlayerPrefs.GetString("123");       // 如果我们之前没有过这个键,那么返回默认值就是Null
​
// 我们是可以修改方法返回的默认值的,另外两个API同理
// 我们通常可以使用在玩家基础数据初始化
PlayerPrefs.GetInt("zzz", 100);     // 如果我们之前没有过这个键,那么返回默认值就是100
​
// PlayerPrefs判断数据是否存在
PlayerPrefs.HasKey("XXX");
​
// PlayerPrefs删除数据
PlayerPrefs.DeleteKey("XXX");       // 删除指定键值对的数据
PlayerPrefs.DeleteAll();            // 删除所有键值对的数据

 参考功能及代码:

通过单选框是否被勾选上,从而来决定是否播放背景音乐,代码如下:

using UnityEngine.UI;
public class MusicManager : MonoBehaviour
{
    // 音乐开关单选框  和 播放背景音乐的 musicAudio 组件
    public Toggle musicToggle;
    public AudioSource musicAudio;
    private void Awake()
    {
      if (PlayerPrefs.HasKey("MusicOn"))
      {
         if (PlayerPrefs.GetInt("MusicOn") == 1)
            {
              //  当 单选框 勾选时, 激活 musicAudio 组件
                musicToggle.isOn = true;
                musicAudio.enabled = true;
            }
            else
            {
            //  当 单选框 未勾选时, 让 musicAudio 组件失活
                musicToggle.isOn = false;
                musicAudio.enabled = false;
            }
      }else
          {
            musicToggle.isOn = true;
          }
    }
    private void Update()
    {
        MusicSwitch();
    }
    private void MusicSwitch() {
         // 通过单选框是否被勾选上,从而来决定是否播放背景音乐
        if (musicToggle.isOn == false)
        {
            musicAudio.enabled = false;
            //   保存音乐开关的状态,   0代表暂停 1 代表播放
            PlayerPrefs.SetInt("MusicOn",0);  
        }
        else {
            musicAudio.enabled = true;
            PlayerPrefs.SetInt("MusicOn", 1);
        }
        PlayerPrefs.Save();
    }
}

二、二进制存储(字节流存储)

序列化:新建或打开一个二进制文件,通过二进制格式器将对象写入该二进制文件。

反序列化:打开待反序列化的二进制文件,通过二进制格式器将文件解析成对象。

参考代码如下:

using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
// 这两个命名空间需添加

// 二进制方法:存档和读档
    private void SaveByBin() {
        // 序列化过程 (将Save 对象转换为字节流)
        // 创建Save 对象 并 保存当前游戏状态 
        Save save = CreateSaveGO();
        // 创建一个二进制格式化程序
        BinaryFormatter bf = new BinaryFormatter();
        // 创建一个文件流
        FileStream fileStream = File.Create(Application.dataPath + "/StreamingFile" + "/byBin.txt");
        // 用二进制格式化程序的序列化方法 来 序列化Save对象
        //      参数:创建的文件流和需要序列化的对象
        bf.Serialize(fileStream,save);
        // 关闭流
        fileStream.Close();

         // 如果文件存在,则显示保存成功
        if (File.Exists(Application.dataPath + "/StreamingFile" + "/byBin.txt")) {
            UIManager._Instance.ShowMessage("保存成功!");
        }
    }
    private void LoadByBin() {

        if (File.Exists(Application.dataPath + "/StreamingFile" + "/byBin.txt"))
        {
            // 反序列化过程
            // 创建一个二进制格式化程序
            BinaryFormatter bf = new BinaryFormatter();
            // 打开一个文件流
            FileStream fileStream = File.Open(Application.dataPath + "/StreamingFile" 
 + "/byBin.txt", FileMode.Open);
            // 调用格式化程序的反序列化方法,将文件流转换为Save 对象
            Save save = (Save)bf.Deserialize(fileStream);
            // 关闭文件流
            fileStream.Close();
            SetGame(save);
            UIManager._Instance.ShowMessage(" ");
        }
        else { 
            UIManager._Instance.ShowMessage("存档文件不存在!");
        }

    }

三、json存储

JSON序列化:对象 ——> JSON

JSON反序列化:JSON ——> 对象

参考代码如下:

using LitJson;
// 此命名空间需添加


// Json:  存档和读档
    private void SaveByJson()
    {
        Save save = CreateSaveGO();
        string filePath = Application.dataPath + "/StreamingFile" + "/byJson.txt";
        // 利用 JsonMapper 将save 对象转换Wie Json 格式的字符串
        string saceJsonStr = JsonMapper.ToJson(save);
        // 将这个字符串写入到文件中
        // 创建一个StreamWriter,并将字符串写入文件中
        StreamWriter sw = new StreamWriter(filePath);
        sw.Write(saceJsonStr);
        // 关闭 StreamWrite
        sw.Close();

        UIManager._Instance.ShowMessage("保存成功!");
    }
   
    private void LoadByJson() {
        string filePath = Application.dataPath + "/StreamingFile" + "/byJson.txt";
        if (File.Exists(filePath))
        {
            // 创建一个 StreamReader, 用来读取流
            StreamReader sr = new StreamReader(filePath);
            // 将读取到的流赋值给 jsonStr
            string jsonStr = sr.ReadToEnd();
            // 关闭
            sr.Close();

            // 将字符串jsonStr 转换为Save 对象
            Save save = JsonMapper.ToObject<Save>(jsonStr);
            SetGame(save);
            UIManager._Instance.ShowMessage(" ");
        }
        else {
            UIManager._Instance.ShowMessage(" 存档文件不存在!");
        }
    }

注:需先导入该文件再添加(using LitJson;)命名空间,LitJson文件存于百度网盘链接:https://pan.baidu.com/s/1Wor_lltGnGbbBmD2T0Dtqg 
提取码:wdrf

四、XML存储

扩展标记语言,用于标记电子文件使其具有结构性的标记语言。 可以用来标记数据、定义数据类型。 序列化与反序列化的方式与二进制方法十分类似。

参考代码如下:

using System.Xml;
//需要添加该命名空间
// Xml:  存档和读档
    private void SaveByXml() {
        Save save = CreateSaveGO();
        // 创建Xml 文件的存储路径
        string filePath = Application.dataPath + "/StreamingFile" + "/byXML.txt";
        // 创建XML 文档
        XmlDocument xmlDoc = new XmlDocument();
        // 创建根节点, 即最上层节点
        XmlElement root = xmlDoc.CreateElement("save");
        // 设置根节点中的值
        root.SetAttribute("name","saveFile1");

        // 创建XmlElement
        XmlElement target;
        XmlElement targetPosition;
        XmlElement monsterType;

        // 遍历 save中存储的数据,将数据转换成XML格式
        for (int i =0; i < save.livingTargetPointions.Count;i++) {
            target = xmlDoc.CreateElement("target");
            targetPosition = xmlDoc.CreateElement("targetPosition");
            // 设置 InnerText 值
            targetPosition.InnerText = save.livingTargetPointions[i].ToString();
            monsterType = xmlDoc.CreateElement("monsterType");
            monsterType.InnerText = save.livingMonsterTypes[i].ToString();

            // 把节点一层层的添加至 XMLDoc 中,请仔细看他们之间的先后顺序,这将是生成XML 文件的顺序
             // 设置节点间的层级关系 root ---- target ---- (targetPosition,monsterType)
            target.AppendChild(targetPosition);
            target.AppendChild(monsterType);
            root.AppendChild(target);
        }
        // 设置射击数和分数节点  并设置层级关系  xmlDoc---- root----(
        //  target---- (targetPosition,monsterType), shootNum , score);
        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);

        xmlDoc.AppendChild(root);
        xmlDoc.Save(filePath);

        if (File.Exists(Application.dataPath + "/StreamingFile" + "/byXML.txt")) { 
            UIManager._Instance.ShowMessage("保存成功!");
        }
    }
    private void LoadByXml() {
        string filePath = Application.dataPath + "/StreamingFile" + "/byXML.txt";
        if (File.Exists(filePath))
        {
            Save save = new Save();
            // 加载XML 文档
            XmlDocument xmlDoc = new XmlDocument();
            xmlDoc.Load(filePath);

            // 通过节点名称来获取元素,结果为XmlNodeList类型
            XmlNodeList targets = xmlDoc.GetElementsByTagName("target");
            // 遍历所有的 target 节点,并获取子节点和子节点的InnerText
            if (targets.Count != 0) {
                foreach (XmlNode target  in targets) {
                    XmlNode targetPosition = target.ChildNodes[0];
                    int targetPositionIndex = int.Parse(targetPosition.InnerText);
                    // 把得到的值存储到 save 中
                    save.livingTargetPointions.Add(targetPositionIndex);
                    XmlNode monsterType = target.ChildNodes[1];
                    int monsterTypeIndex = int.Parse(monsterType.InnerText);
                    save.livingMonsterTypes.Add(monsterTypeIndex);

                }
            }
            // 得到存储的射击数
            XmlNodeList shootNum = xmlDoc.GetElementsByTagName("shootNum");
            int shootNumCount = int.Parse(shootNum[0].InnerText);
            save.shootNum = shootNumCount;

            XmlNodeList score = xmlDoc.GetElementsByTagName("score");
            int scoreCount = int.Parse(score[0].InnerText);
            save.score = scoreCount;
            SetGame(save);
            UIManager._Instance.ShowMessage(" ");
        }
        else {
            UIManager._Instance.ShowMessage("存档文件不存在");
        }
    }

后三种方法优缺点对比:

二进制方法:简单,但可读性差。

XML:可读性强,但是文件庞大,冗余信息多。

JSON:数据格式比较简单,易于读写,但是不直观,可读性比XML差。

参考链接:Unity中使用的四种存档和读档方式_Wisdom_off的博客-CSDN博客_unity 存档文章来源地址https://www.toymoban.com/news/detail-403032.html

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

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

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

相关文章

  • Unity物体移动的几种方式

    主要是Vector3的内置函数以及CharacterController的Move 还有一个固定的每帧进行移动的操作

    2024年02月12日
    浏览(27)
  • Unity——数据存储的几种方式

    PlayerPrefs适合用于 存储简单的键值对数据 存储的数据会在游戏关闭后依然保持,并且可以在不同场景之间共享,适合用于需要在游戏不同场景之间传递和保持的数据。 它利用key-value的方式将数据保存到本地,跟字典类似。然后通过代码进行保存、读取、更新操作。值得注意

    2024年02月03日
    浏览(33)
  • UNITY--读取Excel的几种方式

    目录 一.DLL插件读取 1.1.Excel存放位置 1.2.使用示例 1.3.Excel格式  1.4.输出显示  1.5.所需插件 二.Excel转成Asset文件,再进行读取 2.1Excel文件存放位置 2.2 编辑模式生成Asset文件,并保存到指定位置  2.3创建ExcelRead脚本,读取Excel内容 2.4 创建数据存储脚本 2.5  编辑器生成Asset 与属

    2024年01月20日
    浏览(40)
  • Unity解析JSON的几种方式

    1.使用JsonUtility(Unity自带)解析数据 踩坑 2.使用Newtonsoft.Json dll解析json 链接: link 3.使用LitJson解析数据 4.传递给前端或后端 json

    2024年02月16日
    浏览(34)
  • Python进程间通信常用的几种方式

    1. 队列(Queue) 多个进程使用队列进行数据交换。进程通过队列发送和接收对象。 队列是一个可以存储任意类型数据的数据结构,而且支持多线程操作,因此在Python的多进程编程中,可以利用队列来实现进程间通信。 下面是一个简单的利用队列实现进程间通信的示例代码: 在

    2024年03月26日
    浏览(49)
  • Unity按钮事件的几种绑定方式

    许久没有写C#代码了,对于一些东西自己给整忘了,在此记录下,方便以后自己查阅 获取到按钮组件,我是将代码挂载在其父节点上。 在代码中获取此按钮,并对他就进行绑定。一般都是使用的这类情况。 在脚本中写一个public函数,作为按钮的监听函数,在按钮的Inspector面

    2024年02月11日
    浏览(34)
  • Unity中人物移动的几种方式

    1.使用Transform组件         (1)transform.position(最基础,最常用): 这是通过上下左右键控制人物运动的方法          //获取水平按键,左键或A 则值为-1f,右键或D 则值为1f         horizontal = Input.GetAxis(\\\"Horizontal\\\");         //获取垂直按键,上键或W 则值为-1f,下键或S 则

    2023年04月15日
    浏览(26)
  • 常用的几种服务器端口转发实现方式

    Windows和Linux服务器上实现端口转发的几种常用方式: 硬件路由器转发:这个是2种系统都可以使用的方式。可以通过在硬件路由器上设置端口转发规则,将外部请求转发到内部服务器的指定端口上。 以下为Linux系统实现端口转发的几种方式: iptables命令实现端口转发:iptable

    2024年02月09日
    浏览(32)
  • Unity中获取游戏对象的几种方式

    在学习如何获取物体和组件时先明白说明什么是物体,组件和对象。 物体:unity中在层级显示的东西都可以叫做物体 组件:unity中提供了大量已经写好的组件,比如刚体,碰撞体等,自己 编写的脚本也是一种组件类 对象:挂载到物体上的脚本是一个实例化的组件,也就是一

    2024年01月17日
    浏览(25)
  • 常用的几种布局方式---Flex 布局(垂直居中展示)

    怎样让一个元素在垂直或者水平方向居中显示,可以使用css解决,但是会出现不同浏览器的兼容性问题,而flex布局解决了一个父容器和多个子元素的布局问题,从而灵活布局。 代码展示 在父标签加入display:flex后 垂直布局变成水平布局,如下图所示 在父标签中修改 后又变成

    2024年01月19日
    浏览(37)

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

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

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

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

二维码1

领取红包

二维码2

领红包