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

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

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

在unity中实现对游戏数据的存储和读档的方法主要有这么几种:

  • 使用本地持久化类PlayerPrefs
  • 使用二进制的方法序列化和反序列化(Serialize、Deserialize)
  • 使用Json方法
  • 使用XMl方法。

下面就通过一个简单的例子分别用这四种方法实现数据的存储和读档。


实现目标:
   做一个简单的得分制,按S键得分加一,按B键血量减一。UI设计上做一个保存按钮,用于保存数据,再做一个加载按钮,用于加载上一局保存的数据到场景中。

搭建场景: 由于比较简单,就不一一赘述了,直接上图:
unity本地存储数据,unity,游戏引擎
主要的是说一下unity中Hierarchy面板中的结构,因为担心有些朋友搞混了。
unity本地存储数据,unity,游戏引擎
首先呢,创建一个Canvas,他下面的两个image分别是血量和得分的背景(无关紧要),CurrentBloodVolume是个Text,用来显示当前的血量,CurrentScore也是个Text,用来显示当前的得分,save是个按钮,用来保存,load也是个按钮,用来加载,GameManager是个空物体,用来挂载GameManager脚本,这个脚本里面主要写了各种方法,游戏逻辑,ScoreAndBlood也是个空物体,用来挂载ScoreAndBlood脚本,这个脚本里面写了加分和减血的代码。

脚本创建: 创建一个Date脚本,这个脚本不需要继承MonoBehaviour,因为这个脚本是用来序列化和反序列化的,需要向这个类中添加游戏需要保存的数据,最后要读档的时候也是需要从这个类中读取保存的数据。还需要一个加分和减血的类ScoreAndBlood,最后还有一个游戏主逻辑类GameManager。

我们在最开始先把几段必要的代码给出来:
加分和减血的代码:

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

public class ScoreAndBlood : MonoBehaviour
{
    public static ScoreAndBlood _instance;

    public Text currentBloodVolume;
    public Text currentScore;

    public int BloodVolume = 100;
    public int Score = 0;

    private bool isCanReduce = true;


    private void Awake()
    {
        _instance = this;
    }
    private void Update()
    {
        if (Input.GetKeyDown(KeyCode.B) && isCanReduce)
        {
            BloodVolume--;
            currentBloodVolume.text = BloodVolume.ToString();
            if (BloodVolume < 0)
            {
                isCanReduce = false;
            }
        }
        if (Input.GetKeyDown(KeyCode.S))
        {
            Score++;
            currentScore.text = Score.ToString();
        }
    }
}

需要存储和读取游戏数据的脚本Date:

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

[System.Serializable]
public class Date
{
    public int BloodVolume;
    public int Score;
}

GameManager脚本中向Date中存放数据和从Date中读取数据的方法

  //创建Data对象,并向其中添加游戏需要保存的数据
    private Date GetGameDate()
    {
        Date date = new Date();
        date.BloodVolume = ScoreAndBlood._instance.BloodVolume;
        date.Score = ScoreAndBlood._instance.Score;

        return date; 
    }
    //向游戏中加载Date中保存的数据的方法
    private void SetGameDate( Date date)
    {
        ScoreAndBlood._instance.currentBloodVolume.text = date.BloodVolume.ToString();
        ScoreAndBlood._instance.currentScore.text = date.Score.ToString();
    }

(一)PlayerPrefs
PlayerPrefs是unity提供的一个用于本地数据持久化保存、读取的类。原理很简单,就是利用key—value的方式将数据保存到本地,跟字典类似。然后通过代码进行保存、读取、更新操作。值得注意的是此方法只能保存int型、float型,string型的数据,当然,对于bool类型的可以用0和1来代替真和假,以实现保存目的。

这是用PlayerPrefs方法实现数据存储与读档的,这俩方法写在GameManager中

//用Playerprefs方法对数据进行存储和读档
    private void SaveByPlayerPrefs()
    {
        PlayerPrefs.SetInt("bloodVolume", ScoreAndBlood._instance.BloodVolume);
        PlayerPrefs.SetInt("score", ScoreAndBlood._instance.Score);
        PlayerPrefs.Save();
    }
    private void LoadByPlayerPrefs()
    {
        if (PlayerPrefs.HasKey("bloodVolume") && PlayerPrefs.HasKey("score"))
        {
            ScoreAndBlood._instance.currentBloodVolume.text = PlayerPrefs.GetInt("bloodVolume").ToString();
            ScoreAndBlood._instance.currentScore.text = PlayerPrefs.GetInt("score").ToString();
        }
        else
        {
            Debug.Log("------未找到相应数据------");
        }
        
    }

其中SaveByPlayerPrefs()方法中写了通过PlayerPrefs中的SetInt将血量和得分通过键值对的形式保存下来。LoadByPlayerPrefs()方法中写了先判断一下是否有保存了这两个键,然后再通过GetInt去设置保存下来的值。

这是点击保存游戏和加载游戏按钮要执行的方法

//点击保存和加载游戏的方法
    public void ClickSaveGame()
    {
        SaveByPlayerPrefs();//通过PlayerPrefs方式保存
    }
    public void ClickLoadGame()
    {
        LoadByPlayerPrefs();//通过PlayerPrefs方式读取
    }

(二)序列化和反序列化
保存的时候首先创建二进制格式化程序,然后创建文件流,通过格式化程序将Date进行序列化并保存到本地。读取的时候也是先创建二进制格式化程序,创建文件流,通过格式话程序将Date反序列化出来,然后重新设置游戏数据。

//用二进制方法对数据进行保存和读档
    private void SaveByBin()
    {
        try
        {
            Date date = GetGameDate();
            BinaryFormatter bf = new BinaryFormatter();//创建二进制格式化程序
            using (FileStream fs = File.Create(Application.dataPath + "/SaveFiles" + "/byBin.txt"))  //创建文件流
            {
                bf.Serialize(fs, date); //将date序列化
            }
        }
        catch (System.Exception e)
        {
            Debug.Log(e.Message);
        }
    }
    private void LoadByBin()
    {
        try
        {
            BinaryFormatter bf = new BinaryFormatter();
            using (FileStream fs = File.Open(Application.dataPath + "/SaveFiles" + "/byBin.txt", FileMode.Open))
            {
                Date date = (Date)bf.Deserialize(fs);//将date反序列化并赋值给date
                SetGameDate(date);
            }
        }
        catch (System.Exception e)
        {
            Debug.Log(e.Message);
        }
    }

这里使用using指令是因为文件流创建后需要关闭,如果使用using指令的话就自动关闭掉了,省去了一步关闭的步骤,即fs.Close();

这是点击保存游戏和加载游戏要执行的方法

//点击保存和加载游戏的方法
    public void ClickSaveGame()
    {
        //SaveByPlayerPrefs();//通过PlayerPrefs方式保存
        SaveByBin();//通过二进制的方式保存
    }
    public void ClickLoadGame()
    {
        //LoadByPlayerPrefs();//通过PlayerPrefs方式读取
        LoadByBin();//通过二进制的方式读取
    }

保存成功后可以在SaveFile中看到一个bin文件打开后会看到:
unity本地存储数据,unity,游戏引擎
由此看见,使用二进制的方法可读性不好

(三)Json
这是在unity中使用Json所需要的插件:
https://download.csdn.net/download/qq_41294510/87996770
使用时直接将其拖动到Assets中就可以。
Json是一种轻量级的数据交换格式,使用Json在unity中实现数据的存储与读档是非常方便的。

//用Json方法对数据进行保存和读取
    private void SaveByJson()
    {
        Date date = GetGameDate();
        string datapath = Application.dataPath + "/SaveFiles" + "/byJson.json";
        string dateStr = JsonMapper.ToJson(date);  //利用JsonMapper将date转换成字符串
        StreamWriter sw = new StreamWriter(datapath); //创建一个写入流
        sw.Write(dateStr);//将dateStr写入
        sw.Close();//关闭流

    }
    private void LoadByJson()
    {
        string datePath = Application.dataPath + "/SaveFiles" + "/byJson.json";
        if (File.Exists(datePath ))  //判断这个路径里面是否为空
        {
            StreamReader sr = new StreamReader(datePath);//创建读取流;
            string jsonStr = sr.ReadToEnd();//使用方法ReadToEnd()遍历的到保存的内容
            sr.Close();
            Date date = JsonMapper.ToObject<Date>(jsonStr);//使用JsonMapper将遍历得到的jsonStr转换成Date对象
            SetGameDate(date);
        }
        else
        {
            Debug.Log("------未找到文件------");
        }
    }

以下是点击保存和加载按钮要执行的方法

//点击保存和加载游戏的方法
    public void ClickSaveGame()
    {
        //SaveByPlayerPrefs();//通过PlayerPrefs方式存储
        //SaveByBin();//通过二进制的方式存储
        SaveByJson();//通过Json方式存储
    }
    public void ClickLoadGame()
    {
        //LoadByPlayerPrefs();//通过PlayerPrefs方式读取
        //LoadByBin();//通过二进制的方式读取
        LoadByJson();//通过Json方式读取
    }

保存成功后会看到保存成功后可以在SaveFile中看到一个json文件打开后会看到:
unity本地存储数据,unity,游戏引擎
由此可见,相交与上一种方法可读性要好很多

(四)Xml
XML相较于Json来说可读性要比较好,但文件庞大,格式复杂,没有Json简约。

  //使用XML方法对数据进行保存和读取
    private void SaveByXml()
    {
        Date date = GetGameDate();
        string datePath = Application.dataPath + "/SaveFiles" + "/byXml.txt";
        XmlDocument xmlDoc = new XmlDocument();//创建XML文档
        XmlElement root = xmlDoc.CreateElement("saveByXml");//创建根节点,并设置根节点的名字
        root.SetAttribute("name", "savefile");//设置根节点的值
        //创建其他节点,并设置其他节点的值
        XmlElement bloodVolume = xmlDoc.CreateElement("bloodVolume");
        bloodVolume.InnerText = date.BloodVolume.ToString();
        XmlElement score = xmlDoc.CreateElement("score");
        score.InnerText = date.Score.ToString();
        //将子节点加入根节点,将根节点加入XML文档中
        root.AppendChild(bloodVolume);
        root.AppendChild(score);
        xmlDoc.AppendChild(root);
        xmlDoc.Save(datePath);
        
    }
    private void LoadByXml()
    {
        string datePath = Application.dataPath + "/SaveFiles" + "/byXml.txt";
        if (File.Exists(datePath))
        {
            Date date = new Date();
            XmlDocument xmlDoc = new XmlDocument();
            xmlDoc.Load(datePath);  //加载这个路径下的xml文档

            XmlNodeList bloodVolume = xmlDoc.GetElementsByTagName("bloodVolume");//通过名字得到XML文件下对应的值
            date.BloodVolume = int.Parse(bloodVolume[0].InnerText);

            XmlNodeList score = xmlDoc.GetElementsByTagName("score");
            date.Score = int.Parse(score[0].InnerText);
            SetGameDate(date);
            
        }
        
    }

以下是点击保存按钮和加载按钮的代码:

 //点击保存和加载游戏的方法
    public void ClickSaveGame()
    {
        //SaveByPlayerPrefs();//通过PlayerPrefs方式存储
        //SaveByBin();//通过二进制的方式存储
        //SaveByJson();//通过Json方式存储
        SaveByXml();//通过XML方式存储
    }
    public void ClickLoadGame()
    {
        //LoadByPlayerPrefs();//通过PlayerPrefs方式读取
        //LoadByBin();//通过二进制的方式读取
        //LoadByJson();//通过Json方式读取
        LoadByXml();//通过XML方式读取
    }

保存成功后可以在SaveFile中看到一个txt文件打开后会看到:
unity本地存储数据,unity,游戏引擎
由此看见文件比较大,但是可读性要好。


以下是GameManager的所有代码:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
//引用命名空间
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
using LitJson;
using System.Xml;

public class GameManager : MonoBehaviour
{

    //创建Data对象,并向其中添加游戏需要保存的数据
    private Date GetGameDate()
    {
        Date date = new Date();
        date.BloodVolume = ScoreAndBlood._instance.BloodVolume;
        date.Score = ScoreAndBlood._instance.Score;

        return date; 
    }
    //向游戏中加载Date中保存的数据的方法
    private void SetGameDate( Date date)
    {
        ScoreAndBlood._instance.currentBloodVolume.text = date.BloodVolume.ToString();
        ScoreAndBlood._instance.currentScore.text = date.Score.ToString();
    }

    
    //用Playerprefs方法对数据进行存储和读档
    private void SaveByPlayerPrefs()
    {
        PlayerPrefs.SetInt("bloodVolume", ScoreAndBlood._instance.BloodVolume);
        PlayerPrefs.SetInt("score", ScoreAndBlood._instance.Score);
        PlayerPrefs.Save();
    }
    private void LoadByPlayerPrefs()
    {
        if (PlayerPrefs.HasKey("bloodVolume") && PlayerPrefs.HasKey("score"))
        {
            ScoreAndBlood._instance.currentBloodVolume.text = PlayerPrefs.GetInt("bloodVolume").ToString();
            ScoreAndBlood._instance.currentScore.text = PlayerPrefs.GetInt("score").ToString();
        }
        else
        {
            Debug.Log("------未找到相应数据------");
        }
        
    }


    //用二进制方法对数据进行保存和读档
    private void SaveByBin()
    {
        try
        {
            Date date = GetGameDate();
            BinaryFormatter bf = new BinaryFormatter();//创建二进制格式化程序
            using (FileStream fs = File.Create(Application.dataPath + "/SaveFiles" + "/byBin.txt"))  //创建文件流
            {
                bf.Serialize(fs, date);
            }
        }
        catch (System.Exception e)
        {
            Debug.Log(e.Message);
        }
    }
    private void LoadByBin()
    {
        try
        {
            BinaryFormatter bf = new BinaryFormatter();
            using (FileStream fs = File.Open(Application.dataPath + "/SaveFiles" + "/byBin.txt", FileMode.Open))
            {
                Date date = (Date)bf.Deserialize(fs);
                SetGameDate(date);
            }
        }
        catch (System.Exception e)
        {
            Debug.Log(e.Message);
        }
    }


    //用Json方法对数据进行保存和读取
    private void SaveByJson()
    {
        Date date = GetGameDate();
        string datapath = Application.dataPath + "/SaveFiles" + "/byJson.json";
        string dateStr = JsonMapper.ToJson(date);  //利用JsonMapper将date转换成字符串
        StreamWriter sw = new StreamWriter(datapath); //创建一个写入流
        sw.Write(dateStr);//将dateStr写入
        sw.Close();//关闭流

    }
    private void LoadByJson()
    {
        string datePath = Application.dataPath + "/SaveFiles" + "/byJson.json";
        if (File.Exists(datePath ))  //判断这个路径里面是否为空
        {
            StreamReader sr = new StreamReader(datePath);//创建读取流;
            string jsonStr = sr.ReadToEnd();//使用方法ReadToEnd()遍历的到保存的内容
            sr.Close();
            Date date = JsonMapper.ToObject<Date>(jsonStr);//使用JsonMapper将遍历得到的jsonStr转换成Date对象
            SetGameDate(date);
        }
        else
        {
            Debug.Log("------未找到文件------");
        }
    }


    //使用XML方法对数据进行保存和读取
    private void SaveByXml()
    {
        Date date = GetGameDate();
        string datePath = Application.dataPath + "/SaveFiles" + "/byXml.txt";
        XmlDocument xmlDoc = new XmlDocument();//创建XML文档
        XmlElement root = xmlDoc.CreateElement("saveByXml");//创建根节点,并设置根节点的名字
        root.SetAttribute("name", "savefile");//设置根节点的值
        //创建其他节点,并设置其他节点的值
        XmlElement bloodVolume = xmlDoc.CreateElement("bloodVolume");
        bloodVolume.InnerText = date.BloodVolume.ToString();
        XmlElement score = xmlDoc.CreateElement("score");
        score.InnerText = date.Score.ToString();
        //将子节点加入根节点,将根节点加入XML文档中
        root.AppendChild(bloodVolume);
        root.AppendChild(score);
        xmlDoc.AppendChild(root);
        xmlDoc.Save(datePath);
        
    }
    private void LoadByXml()
    {
        string datePath = Application.dataPath + "/SaveFiles" + "/byXml.txt";
        if (File.Exists(datePath))
        {
            Date date = new Date();
            XmlDocument xmlDoc = new XmlDocument();
            xmlDoc.Load(datePath);  //加载这个路径下的xml文档

            XmlNodeList bloodVolume = xmlDoc.GetElementsByTagName("bloodVolume");//通过名字得到XML文件下对应的值
            date.BloodVolume = int.Parse(bloodVolume[0].InnerText);

            XmlNodeList score = xmlDoc.GetElementsByTagName("score");
            date.Score = int.Parse(score[0].InnerText);
            SetGameDate(date);
            
        }
        
    }

    //点击保存和加载游戏的方法
    public void ClickSaveGame()
    {
        //SaveByPlayerPrefs();//通过PlayerPrefs方式存储
        //SaveByBin();//通过二进制的方式存储
        //SaveByJson();//通过Json方式存储
        SaveByXml();//通过XML方式存储
    }
    public void ClickLoadGame()
    {
        //LoadByPlayerPrefs();//通过PlayerPrefs方式读取
        //LoadByBin();//通过二进制的方式读取
        //LoadByJson();//通过Json方式读取
        LoadByXml();//通过XML方式读取
    }
}

好了,以上就是使用这四种方法保存与读取数据的一个简单案例。具体使用那种方法还是要按照实际情况来。文章来源地址https://www.toymoban.com/news/detail-722696.html

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

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

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

相关文章

  • 简单介绍ES中的索引存储类型

    老铁们好,我是V,今天我们简单聊聊ES中的索引存储类型 目前ES中主要支持以下几种存储类型 fs 默认文件系统实现。这将根据操作环境选择最佳实施,目前会默认启用hybridfs simplefs Simple FS 类型是 SimpleFsDirectory 使用随机访问文件的文件系统存储(映射到 Lucene)的直接实现。这

    2024年04月28日
    浏览(40)
  • Python爬虫数据存哪里|数据存储到文件的几种方式

    前言 大家早好、午好、晚好吖 ❤ ~欢迎光临本文章 爬虫请求解析后的数据,需要保存下来,才能进行下一步的处理,一般保存数据的方式有如下几种: 文件:txt、csv、excel、json等,保存数据量小。 关系型数据库:mysql、oracle等,保存数据量大。 非关系型数据库:Mongodb、R

    2024年02月09日
    浏览(52)
  • js~在浏览器中对用户名和密码进行存储

    btoa() 和 atob() 是 JavaScript 中的标准函数,通常在现代浏览器中都能正常工作。然而,它们在处理非 ASCII 字符时可能存在一些兼容性问题。 这些函数的主要限制在于它们仅支持 ASCII 字符集,对于非 ASCII 字符(如 Unicode 字符)可能会产生不可预测的结果。在处理非 ASCII 字符时

    2024年02月09日
    浏览(45)
  • 在Java中对XML的简单应用

    1.1 什么是 XML XML 指可扩展标记语言(EXtensible Markup Language)。 XML 是一种很像HTML的标记语言。 XML 的设计宗旨是传输数据,而不是显示数据。 XML 标签没有被预定义。您需要自行定义标签。 XML 被设计为具有自我描述性。 XML 是 W3C 的推荐标准 1.2 XML 与 HTML 的主要差异 XML 不是

    2024年02月13日
    浏览(44)
  • unity GC机制简单介绍

    GC全称是garbage collection,即垃圾回收,顾名思义就是一种释放内存垃圾的机制。这种机制主要作用在堆空间上。 堆上的变量在存储的时候,主要分为以下几步: 1)首先,unity检测是否有足够的闲置内存单元用来存储数据,如果有,则分配对应大小的内存单元; 2)如果没有足

    2024年02月04日
    浏览(36)
  • Unity Android 之 读取下载获取移动端 sdcard 路径下的指定文件夹的所有图片的几种方式的简单整理

    目录 Unity Android 之 读取下载获取移动端 sdcard 路径下的指定文件夹的所有图片的几种方式的简单整理 一、简单介绍 二、实现原理 三、注意事项 四、简单实现步骤 五、关键代码 附录: 一、不同平台使用宏区分路径加载 二、Unity3D中的资源路径 三、Unity3D各平台路径(包括手

    2024年01月19日
    浏览(84)
  • 【Unity ShaderGraph】| Shader Graph入门介绍 | 简介 | 配置环境 | 窗口介绍 | 简单案例

    前言 Unity2018版本之后推出了一款名为 Shader Graph 的可编程渲染管线工具。 这个工具可以通过可视化界面拖拽来实现着色器的创建和编辑,大大简化了着色器的制作过程,同时着色效果编译显示也快。 下面就来介绍一下Shader Graph的基本信息及使用方法,上手非常简单,一起来

    2024年02月08日
    浏览(39)
  • Unity笔记:数据持久化的几种方式

    主要方法: ScriptableObject PlayerPrefs JSON XML 数据库(如Sqlite) PlayerPrefs 存储的数据是 全局共享 的,它们存储在用户设备的本地存储中,并且可以被应用程序的所有部分访问。这意味着,无论在哪个场景、哪个脚本中,只要是同一个应用程序中的代码,都可以读取和修改 Playe

    2024年02月19日
    浏览(44)
  • MMDetection中对Resnet增加注意力机制Attention的简单方法

    以resnet为例子,我在多个尺度的特征层输出增加注意力机制,以此编写一个基类,子类只需要实现这个attention即可。 参考开源仓库实现attention: GitHub - xmu-xiaoma666/External-Attention-pytorch: 🍀 Pytorch implementation of various Attention Mechanisms, MLP, Re-parameter, Convolution, which is helpful to furth

    2024年02月15日
    浏览(95)
  • STM32学习笔记———几种简单传感器的数据读取

    传感器正如计算机的眼睛。从广义上讲,传感器就是一种能感知外界信息,并将这些信息按照一定规律转换成可用的电信号或其他形式的输出信号的装置,达到对信息的存储,传输,控制的目的。本文着重分析如何通过单片机分析电信号时序图实现对传感器的控制与传感器采

    2023年04月23日
    浏览(45)

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

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

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

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

二维码1

领取红包

二维码2

领红包