Unity 数据存储和读取的方法汇总
作者:Mr.Cat~ 发布时间:2021-12-12 11:39:47
在 Unity 中实现对游戏数据存储和读取的方法主要有这几种:
使用本地持久化类 PlayerPrefs
使用二进制的方法序列化和反序列化(Serialize / Deserialize)
使用 Json 方法
使用 XML 方法
数据场景
在 Demo 中分别使用这四种方法实现面板上数据的存储和读取
创建一个 Data 脚本用来序列化和反序列化,需要向这个类中添加需要保存的数据,最后也是需要从这个类中读取保存的数据
需要存储和读取数据的脚本 Data
[System.Serializable]
public class Data
{
// 关卡/生命值/关卡得分
public int levels;
public int health;
public int scores;
}
向 Data 中存储和读取数据的方法
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
/// <summary>
/// 数据管理
/// </summary>
public class DataManager : MonoBehaviour
{
// 创建 Data 对象,并添加需要保存的数据
private Data GetGameData()
{
Data data = new Data();
data.levels = CanvasManager.Instance.levels;
data.health = CanvasManager.Instance.health;
data.scores = CanvasManager.Instance.scores;
return data;
}
// 向游戏中加载 Data 中保存的数据
private void SetGameData(Data data)
{
CanvasManager.Instance.levels = data.levels;
CanvasManager.Instance.health = data.health;
CanvasManager.Instance.scores = data.scores;
CanvasManager.Instance.DataUpdate();
}
}
PlayerPrefs
Playerprefs 是 Unity 提供的一个用于本地数据持久化保存和读取的类
原理就是利用 Key - Value 的方式将数据保存到本地(跟字典类似),然后通过代码实现数据保存、读取和更新的操作
* PlayerPrefs 只能保存 int 型、float 型和 string 型的数据,对于 bool 类型可以用 1/0 代替 真/假,实现保存的目的 *
// 数据存储:PlayerPrefs
private void SaveByPlayerPrefs()
{
PlayerPrefs.SetInt("Levels", CanvasManager.Instance.levels);
PlayerPrefs.SetInt("Health", CanvasManager.Instance.health);
PlayerPrefs.SetInt("Scores", CanvasManager.Instance.scores);
PlayerPrefs.Save();
}
// 数据读取:PlayerPrefs
private void LoadByPlayerPrefs()
{
if (PlayerPrefs.HasKey("Levels") && PlayerPrefs.HasKey("Health") && PlayerPrefs.HasKey("Scores"))
{
CanvasManager.Instance.levels = PlayerPrefs.GetInt("Levels");
CanvasManager.Instance.health = PlayerPrefs.GetInt("Health");
CanvasManager.Instance.scores = PlayerPrefs.GetInt("Scores");
CanvasManager.Instance.DataUpdate();
}
else
Debug.Log("- 未找到相应数据 -");
}
通过 PlayerPrefs 中的 SetInt() 将面板上的数据通过键值对的形式进行存储;然后通过 GetInt() 去读取保存下来的值
面板上保存数据和加载数据按钮执行的方法
// 保存游戏数据
public void SaveGameData()
{
SaveByPlayerPrefs(); //通过 PlayerPrefs 方式保存
}
// 加载游戏数据
public void LoadGameData()
{
LoadByPlayerPrefs(); //通过 PlayerPrefs 方式读取
}
序列化与反序列化
保存的时候:
首先创建二进制格式化程序,然后创建文件流,通过格式化程序将 Data 进行序列化并保存到本地
读取的时候:
先创建二进制格式化程序,然后创建文件流,通过格式化程序将 Data 反序列化出来,然后重新设置数据
// 数据存储:二进制方法
private void SaveByBin()
{
try
{
Data data = GetGameData();
// 创建二进制格式化程序
BinaryFormatter bf = new BinaryFormatter();
using (FileStream fs = File.Create(Application.dataPath + "/SaveFiles" + "/ByBin.Txt"))
{
// 将 data 序列化
bf.Serialize(fs, data);
}
}
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))
{
// 将 data 反序列化
Data data = (Data)bf.Deserialize(fs);
SetGameData(data);
}
}
catch (System.Exception e)
{
Debug.Log(e.Message);
}
}
* 文件流创建使用后需要及时关闭,即 fs.Close() *
在这里使用 using 指令的话就会自动关闭,省略了一步关闭的步骤
面板上保存数据和加载数据按钮执行的方法
// 保存游戏数据
public void SaveGameData()
{
//SaveByPlayerPrefs(); //通过 PlayerPrefs 方式保存
SaveByBin(); //通过二进制方式
}
// 加载游戏数据
public void LoadGameData()
{
//LoadByPlayerPrefs(); //通过 PlayerPrefs 方式读取
LoadByBin(); //通过二进制方式读取
}
保存成功后可以在 SaveFiles 文件夹中看到一个 ByBin.txt 文件
Json
json 是一种轻量级的数据交换格式,使用 Json 在 Unity 中实现数据的存储和读取是非常方便的
* 需要导入使用 Json 所需要的插件 *
// 数据存储:Json
private void SaveByJson()
{
Data data = GetGameData();
string dataPath = Application.dataPath + "/SaveFiles" + "/ByJson.json";
// 利用 JsonMapper 将 data 转换成字符串
string dataStr = JsonMapper.ToJson(data);
// 创建写入流写入数据
StreamWriter sw = new StreamWriter(dataPath);
sw.Write(dataStr);
// 关闭流
sw.Close();
}
// 数据读取:Json
private void LoadByJson()
{
string dataPath = Application.dataPath + "/SaveFiles" + "/ByJson.json";
// 判断路径文件
if (File.Exists(dataPath))
{
// 创建读取流读取数据
StreamReader sr = new StreamReader(dataPath);
string jsonStr = sr.ReadToEnd();
sr.Close();
// 使用 JsonMapper 将得到的 jsonStr 转换为 data 对象
Data data = JsonMapper.ToObject<Data>(jsonStr);
SetGameData(data);
}
else
Debug.Log("- 未找到相应文件 -");
}
面板上保存数据和加载数据按钮执行的方法
// 保存游戏数据
public void SaveGameData()
{
//SaveByPlayerPrefs(); //通过 PlayerPrefs 方式保存
//SaveByBin(); //通过二进制方式存储
SaveByJson(); // 通过 Json 方式存储
}
// 加载游戏数据
public void LoadGameData()
{
//LoadByPlayerPrefs(); //通过 PlayerPrefs 方式读取
//LoadByBin(); //通过二进制方式读取
LoadByJson(); //通过 Json 方式读取
}
保存成功后可以在 SaveFiles 文件夹中看到一个 json 文件
相较于上一种方法,Json 数据的可读性要好很多
XML
XML 相较于 Json 来说可读性比较好,但文件庞大,格式复杂,没有 Json 简约
// 数据存储:Xml
private void SaveByXml()
{
Data data = GetGameDate();
string dataPath = Application.dataPath + "/SaveFiles" + "/ByXml.txt";
// 创建 Xml 文档
XmlDocument xmlDoc = new XmlDocument();
// 创建根节点并设置名称
XmlElement root = xmlDoc.CreateElement("SaveByXml");
root.SetAttribute("name", "savefile");
// 创建其他节点并设置值
XmlElement levels = xmlDoc.CreateElement("levels");
levels.InnerText = data.levels.ToString();
XmlElement health = xmlDoc.CreateElement("health");
health.InnerText = data.health.ToString();
XmlElement scores = xmlDoc.CreateElement("scores");
scores.InnerText = data.scores.ToString();
// 将子节点加入根节点,并将根节点加入 Xml 文档
root.AppendChild(levels);
root.AppendChild(health);
root.AppendChild(scores);
xmlDoc.AppendChild(root);
xmlDoc.Save(dataPath);
}
// 数据读取:Xml
private void LoadByXml()
{
string dataPath = Application.dataPath + "/SaveFiles" + "/ByXml.txt";
if (File.Exists(dataPath))
{
Data data = new Data();
XmlDocument xmlDoc = new XmlDocument();
// 加载指定路径的 Xml 文档
xmlDoc.Load(dataPath);
// 通过名字得到相对应的值
XmlNodeList levels = xmlDoc.GetElementsByTagName("levels");
data.levels = int.Parse(levels[0].InnerText);
XmlNodeList health = xmlDoc.GetElementsByTagName("health");
data.health = int.Parse(health[0].InnerText);
XmlNodeList scores = xmlDoc.GetElementsByTagName("scores");
data.scores = int.Parse(scores[0].InnerText);
SetGameDate(data);
}
else
Debug.Log("- 未找到相应文件 -");
}
面板上保存数据和加载数据按钮执行的方法
// 保存游戏数据
public void SaveGameData()
{
//SaveByPlayerPrefs(); //通过 PlayerPrefs 方式保存
//SaveByBin(); //通过二进制方式存储
//SaveByJson(); //通过 Json 方式存储
SaveByXml(); //通过 Xml 方式存储
}
// 加载游戏数据
public void LoadGameData()
{
//LoadByPlayerPrefs(); //通过 PlayerPrefs 方式读取
//LoadByBin(); //通过二进制方式读取
//LoadByJson(); //通过 Json 方式读取
LoadByXml(); //通过 Xml 方式读取
}
保存成功后可以在 SaveFiles 文件夹中看到一个 txt 文件
来源:https://www.cnblogs.com/Haha1999/p/16803479.html


猜你喜欢
- ssm(spring springMVC mybatis)1.创建项目file->new->project2.新建的maven项
- 一、概述本文描述采用C#语言访问控制Tektronix TBS 2000B 系列示波器。接口协议采用NI-VISA。最近一个项目需要和一款示
- 本文实例讲述了Android实现Service获取当前位置(GPS+基站)的方法。分享给大家供大家参考。具体如下:需求详情:1)、Servi
- 本文实例为大家分享了Java实现简单日历界面的具体代码,供大家参考,具体内容如下请使用JFrame、JPanel、JButton、JLabe
- 之前调用 WebService 都是直接添加服务引用,然后调用 WebService 方法的,最近发现还可以使用 Http 请求调用 Web
- Servlet:当然,在servlet中,一般跳转都发生在doGet, doPost等方法里面。1) redirect 方式response
- ImGUI 它是与平台无关的C++轻量级跨平台图形界面库,没有任何第三方依赖,可以将ImGUI的源码直接加到项目中使用,该框架通常会配合特定
- java简单模拟微信抢红包功能,本例发100元红包,有10个人抢,为了尽可能的公平,每个人的红包金额都要随机(保证结果的不确定性,本例抢红包
- 现在很多网站都有注册登录的页面,为了更好的满足用户体验和网站的安全性,很多网站都采用动态生成的图形码或者是附加码进行验证,下面把生成验证码的
- 小米系统自带的长截屏应该很多人都用过,效果不错。当长截屏时listview就会自动滚动,当按下停止截屏时,就会得到一张完整的截屏。该篇就介绍
- 1. 参数中直接加入%%param.setUsername("%CD%"); param.set
- 使用InsertProvider注解报错解决目前项目在使用mybatis,并且是使用注解的方式。在使用InsertProvider注解的时候
- 从Map、JSONObject取不存在键值对时异常1.在Map中取不存在的键值对时不会报异常只会返回null@Test
- 配置文件请看上篇Java实现redis https://www.jb51.net/article/190922.htm下面测试redis的集
- > 此文主要通过WinForm来制作一个休息提醒闹钟,通过设置时间间隔进行提醒,避免沉浸式的投入到工作或者学习当中,战斗的同时也要照顾
- 一般要做正圆形图片,只能是正方形的基础上才能实现,否则就变成椭圆了,下面说说如何使长方形的图片生成正圆形图片废话不多说,没图没真相,先上图吧
- 使用WebSocketSharp自定义实现Web服务时,无法解析multipart/form-data请求的数据。通过查找资料,采用以下方式
- C# FileStream类在 C# 语言中文件读写流使用 FileStream 类来表示,FileStream 类主要用于文件的读写,不仅
- 一、前置说明本节大纲使用lombok插件的好处如何安装lombok插件使用lombok提高开发效率二、使用lombok插件的好处我们在jav
- 程序触发鼠标、键盘事件是C#程序设计中比较常见的功能,本文实例展示了C#中winform实现自动触发鼠标、键盘事件的方法,有不错的实用价值。