【Unity学习日记03】数据持久化

这篇具有很好参考价值的文章主要介绍了【Unity学习日记03】数据持久化。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

这一篇只能说写了一部分,并没有把Unity里数据持久化的操作讲完整,之后可能是学到一点就记一点的模式。

1 概念

数据持久化就是将内存中的数据模型转换为存储模型,以及将存储模型转换为内存中的数据模型的统称。

人话版:将游戏数据存储到硬盘,硬盘中数据读取到游戏中,也就是传统意义上的存盘。

unity数据持久化,unity,学习,游戏引擎

2 PlayerPrefs

2.1 概念

PlayerPrefs是Unity提供的一个可以用于存储读取玩家数据的公共类。

2.2 操作

1 存储

PlayerPrefs的数据存储类似于键值对,一个键对应一个值。它提供了3种数据存储方式:int,float,string。

键:string。
值:int,float,string,对应3种API。

PlayerPrefs.SetInt("Age", 18);
PlayerPrefs.SetFloat("Height", 100);
PlayerPrefs.SetString("Name", ",manqi");

需要注意的是,直接调用API只会把数据存储到内存中。当游戏结束时,才会自动把数据存到硬盘中。

如果游戏不是正常结束(崩溃等),数据是不会存到硬盘中的。为了能立刻将数据存储到硬盘中,避免丢失的情况,我们可以用PlayerPrefs.Save()。

PlayerPrefs.Save();  //将数据立刻存储到硬盘中

然而我们可以看到PlayerPrefs是有局限性的,它只能存储3种类型的数据,如果有其他类型需求,只能降低精度或者转变类型(如bool的true存储为int的1)。

另外,需要注意,如果同一键名存储,无论数据类型是否变化,都会将原来的数据覆盖。(所以我们要保证key的唯一性。

PlayerPrefs.SetInt("Age",18);
PlayerPrefs.SetString("Age","18");

2 读取

用int举例:

//如果没有对应键,会传出默认值,如int-0。
int age = PlayerPrefs.GetInt("Age");
//如果找不到对应键,会传出函数第二个参数。
int age = PlayerPrefs.GetInt("Age",100);

判断数据是否存在:

if(PlayerPrefs.HasKey("Age")){
	print("存在");
}

3 删除

//删除指定键值对
PlayerPrefs.DeleteKey("Age");
PlayerPrefs.DeleteAll();

2.3 Windows存储位置

PlayerPrefs存储在HKEY_CURRENT_USER\Software[公司名][产品名] 项下的注册表中。(其中公司名和产品名是“File->Build Setting->Project Settings->Player”中设置的名称。

unity数据持久化,unity,学习,游戏引擎

unity数据持久化,unity,学习,游戏引擎
但我们会发现,当我们直接修改注册表内数据信息时,游戏内读取到的数据也会对应改变,这是用PlayerPrefs存储信息的缺陷。针对这个缺陷,我们可以进行加密或者是采取其他的数据存储方式。

2.4 优缺点分析

优点:简单易懂方便操作。
缺点:①能直接存储的数据类型有限,复杂类型的存储需要自己实现;②数据安全性低,容易被修改。
适用范围:适合用来存储暂时性数据,如玩家偏好设定。

2.5 自定义类的存储

自定义类的存储我们可以利用PlayerPrefs的SetString API以及JsonUtility。

方法类

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

public static class SaveSystem{
    public static void SaveByPlayerPrefs(string key,object data) {
        var json = JsonUtility.ToJson(data);
        PlayerPrefs.SetString(key, json);
        PlayerPrefs.Save();
    }
    public static string LoadFromPlayerPrefs(string key) {
        return PlayerPrefs.GetString(key, null) ;
    }
}

调用类

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

public class Test : MonoBehaviour {
    //增加可序列化特性才能被JsonUtility转换
    [System.Serializable]
    class SaveData {
        public string playerName;
        public string playerLevel;
        public string playerCoin;
        public Vector3 playerPosition;
    }
    const string PLAYER_DATA_KEY = "PlayerData";
    public string playerName;
    public string playerLevel;
    public string playerCoin;
    public Vector3 playerPosition;

    //存档
    SaveData SavingData() {
        var savaData = new SaveData();
        savaData.playerName = playerName;
        savaData.playerLevel = playerLevel;
        savaData.playerCoin = playerCoin;
        savaData.playerPosition = playerPosition;
        return savaData;
    }
    void SaveByPlayerPrefs() {
        SaveSystem.SaveByPlayerPrefs(PLAYER_DATA_KEY, SavingData());
    }
    //读档
    void LoadFromPlayerPrefs() {
        var json = SaveSystem.LoadFromPlayerPrefs(PLAYER_DATA_KEY);
        var saveData = JsonUtility.FromJson<SaveData>(json);
    }
    void LoadData(SaveData saveData) {
        playerName = saveData.playerName;
        playerLevel = saveData.playerLevel;
        playerName = saveData.playerName;
        playerPosition = saveData.playerPosition;
    }
    //删除
    void DeletePlayerDataPrefs() {
        PlayerPrefs.DeleteKey(PLAYER_DATA_KEY);
    }
}

3 JSON

3.1 概念

在Unity中,JSON(JavaScript Object Notation)是一种常见的数据交换格式。Unity内置了JsonUtility类,可以用于将对象序列化为JSON字符串或将JSON字符串反序列化为对象。

unity数据持久化,unity,学习,游戏引擎

3.2 JsonUtility

JsonUtility是Unity内用来处理Json数据的类,相关API:JsonUtility
unity数据持久化,unity,学习,游戏引擎

1 JsonUtility.ToJson

第一个参数必须支持Unity序列化,具体是否能被序列化见【3.3】。
第二个参数指的是是否转换为更适合阅读的Json文本格式。

var json = JsonUtility.ToJson(object);
var json = JsonUtility.ToJson(object,bool);

另外,需要注意的是,如果data为空:

bool data;
print(JsonUtility.ToJson(data));

此时控制台只会打印出一个{},因为Json序列化的对象是数据本身,而data本身没有存储任何数据,此时Json会尝试序列化,但它会发现序列化的内容为空,因此只会打印出一个{}。

如果我们希望Json能正确转换字段,我们可以直接转换封装的类本身。

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

public class ToJsonTest : MonoBehaviour{
    [System.Serializable] class Player {
        public string playerName;
        public bool isDie;
        public int health;
    }
    void Start(){
        Player player = new Player();
        print(JsonUtility.ToJson(player));   
    }
}

unity数据持久化,unity,学习,游戏引擎

2 JsonUtility.FromJson

public static T FromJson(string json);

3 JsonUtility.FromJsonOverwrite

转换后的数据覆盖第二个参数传入的object。

public static void FromJsonOverwrite(string json,object objectToOverwrite);

3.3 支持/不支持Unity序列化

简单的判断是否能被Unity序列化的方法:
将类型标记为public或者在前面标上[SerializeField]特性,看该类型是否能在Inspector窗口显示。
PS:JsonUtility类只支持序列化和反序列化C#对象,不支持序列化和反序列化Unity的组件和对象。

具体的:

1 字段

unity数据持久化,unity,学习,游戏引擎

2 类

unity数据持久化,unity,学习,游戏引擎
unity数据持久化,unity,学习,游戏引擎

3.4 基于Json的简易存档系统

方法类

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

public static class SaveSystem{
    public static void SaveByJson(string saveFileName,object data) {
        var json = JsonUtility.ToJson(data);
        //Application.persistentDataPath:Unity提供的一个存储永久数据的路径:不同平台上路径不同。
        //Path.Combine:合并传入的路径。
        var path = Path.Combine(Application.persistentDataPath, saveFileName) ;
        //File.WriteAllText方法用于写入字符串类型的数据,而Json是字符串类型。
        File.WriteAllText(path, json);
    }
    public static T LoadFromJson<T>(string saveFileName) {
        var path = Path.Combine(Application.persistentDataPath, saveFileName);
        var json = File.ReadAllText(path);
        var data = JsonUtility.FromJson<T>(json);
        return data;
    }
    public static void DeleteSaveFile(string saveFileName) {
        var path = Path.Combine(Application.persistentDataPath, saveFileName);
        File.Delete(path);
    }
}

调用类

using System.Collections;
using System.Collections.Generic;
using Unity.VisualScripting;
using UnityEngine;

public class Test : MonoBehaviour{
    //增加可序列化特性才能被JsonUtility转换
    [System.Serializable]class SaveData {
        public string playerName;
        public string playerLevel;
        public string playerCoin;
        public Vector3 playerPosition;
    }
    const string PLAYER_DATA_KEY = "PlayerData";
    const string PLAYER_DATA_FILE_NAME = "PlayerData";
    public string playerName;
    public string playerLevel;
    public string playerCoin;
    
    //存档
    SaveData SavingData() {
        var saveData = new SaveData();
        saveData.playerName = playerName;
        saveData.playerLevel = playerLevel;
        saveData.playerCoin = playerCoin;
        saveData.playerPosition = transform.position;
        return saveData;
    }
    void SaveByJson() {
        SaveSystem.SaveByJson(PLAYER_DATA_FILE_NAME, SavingData());
    }
    //读档
    void LoadFromJson() {
        var saveData = SaveSystem.LoadFromJson<SaveData>(PLAYER_DATA_FILE_NAME);
        LoadData(saveData);
    }
    void LoadData(SaveData saveData) {
        playerName = saveData.playerName;
        playerLevel = saveData.playerLevel;
        playerCoin = saveData.playerCoin;
        transform.position = saveData.playerPosition;
    }
    //删除
    void DeletePlayerDataFiles() {
        SaveSystem.DeleteSaveFile(PLAYER_DATA_FILE_NAME);
    }
}

3.6 优缺点分析

优点:①更符合人类的阅读习惯;②广泛使用,适用多编程语言;③轻量级,易于网络传输与机器解析和生成。
缺点:①支持的数据类型有限(因为是通过Unity的序列化程序实现的;②数据安全性低。
适用范围:
联网:①优秀的网络数据交换载体;②云存档。
本地存储:①非敏感而需要大量读取和修改的数据,如Mod;②玩家的偏好设置。

4 XML

4.1 概念

在Unity中,XML(Extensible Markup Language)是一种常见的数据交换格式。Unity提供了System.Xml命名空间下的类库,可以用于将XML数据序列化为对象或将对象反序列化为XML数据。

<?xml version="1.0" encoding="UTF-8"?>
<student>
  <student1 name="椎名">
    <age>5</age>
    <sex>man</sex>
  </student1>
  <student2 name="mikan">
    <age>10</age>
    <sex>woman</sex>
  </student2>
  <student3 name="みかん">
    <age>15</age>
    <sex>woman</sex>
  </student3>
</student>

4.2 基于XML的简易存档系统

请注意,由于Unity默认不支持使用XmlSerializer类,因此我们需要在Assets文件夹中创建一个空的XML文件夹,并将MonoXml.dll文件从Windows的.NET Framework文件夹中拷贝到该文件夹中。

方法类

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.IO;
using System.Xml.Serialization; 

public static class SaveSystem {
    //存储
    public static void SaveByXml(string saveFileName, object data) {
        //创建XmlSerializer对象,传入待序列化数据的类型。
        var serializer = new XmlSerializer(data.GetType());
        //创建FileStream对象,指定文件路径和操作模式。
        string path = Path.Combine(Application.persistentDataPath, saveFileName);
        var stream = new FileStream(path, FileMode.Create);
        //序列化数据,并写入文件
        serializer.Serialize(stream, data); 
        stream.Close();
    }

    //读取
    public static T LoadFromXml<T>(string saveFileName) {
        //创建XmlSerializer对象,传入待反序列化数据的类型
        var serializer = new XmlSerializer(typeof(T));
        //创建FileStream对象,指定文件路径和操作模式。
        string path = Path.Combine(Application.persistentDataPath, saveFileName);
        var stream = new FileStream(path, FileMode.Create);
        //从文件中反序列化数据,并转换为指定类型
        var data = (T)serializer.Deserialize(stream); 
        stream.Close(); 
        return data; 
    }

    //删除
    public static void DeleteSaveFile(string saveFileName) {
        var path = Path.Combine(Application.persistentDataPath, saveFileName);
        File.Delete(path);
    }
}

调用类文章来源地址https://www.toymoban.com/news/detail-521836.html

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

public class Test : MonoBehaviour {
    //增加可序列化特性才能被转换
    [System.Serializable]
    class SaveData {
        public string playerName;
        public string playerLevel;
        public string playerCoin;
        public Vector3 playerPosition;
    }
    public string playerName;
    public string playerLevel;
    public string playerCoin;
    public Vector3 playerPosition;
    const string PLAYER_DATA_FILE_NAME = "PlayerData";

    SaveData SavingData() {
        var savaData = new SaveData();
        savaData.playerName = playerName;
        savaData.playerLevel = playerLevel;
        savaData.playerCoin = playerCoin;
        savaData.playerPosition = playerPosition;
        return savaData;
    }
    //存档
    void SaveByXML() {
        SaveSystem.SaveByXml(PLAYER_DATA_FILE_NAME,SavingData());
    }
    //读档
    void LoadFromJson() {
        var saveData = SaveSystem.LoadFromXml<SaveData>(PLAYER_DATA_FILE_NAME);
        LoadData(saveData);
    }
    void LoadData(SaveData saveData) {
        playerName = saveData.playerName;
        playerLevel = saveData.playerLevel;
        playerCoin = saveData.playerCoin;
        transform.position = saveData.playerPosition;
    }
    //删除
    void DeletePlayerDataFiles() {
        SaveSystem.DeleteSaveFile(PLAYER_DATA_FILE_NAME);
    }

}

到了这里,关于【Unity学习日记03】数据持久化的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

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

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

相关文章

  • Unity之数据持久化——Json

    JavaScript对象简谱(JavaScript Object Notation) json是国际通用的一种轻量级的数据交换格式,主要在网络通讯中用于传输数据,或本地数据存储和读取,易于人阅读和编写,同时也易于机器解析和生成,并有效地提升网络传输效率 游戏中可以把游戏数据按照Json的格式标准存储在

    2023年04月20日
    浏览(30)
  • Unity数据持久化之PlayerPrefs

    什么是数据持久化 数据持久化就是将内存中的数据模型转换为存储模型,以及将存储模型转换为内存中的数据模型的统称。即将游戏数据存储到硬盘,硬盘中数据读取到游戏中,也就是传统意义上的存盘。 PlayerPrefs是什么 是 Unity 提供的可以用于存储读取玩家数据的公共类

    2024年02月19日
    浏览(34)
  • Unity PlayerPrefs 持久化数据存在哪

    在游戏开发的过程中,我们经常需要存档相关的东西,称为数据的持久化。PlayerPrefs 就是Unity提供的用于本地数据持久化保存与读取的类。 PlayerPrefs会以键值对的方式存储在本地的注册表中。 1.存储数据 2.获取数据 3.删除数据 这些数据会存储在注册表中,打开注册表就能查看

    2024年02月16日
    浏览(33)
  • 【Unity】数据持久化路径Application.persistentDataPath

    今天突然想到这个路径Application.persistentDataPath,热更的重要路径,该文件夹可读可写,在移动端唯一一个可读写操作的文件夹。 移动端可以将本地的资源(资源MD5值配置表)等一些文件放到StreamingAssets文件夹下,通过Copy到persistentDataPath下与服务器的版本文件配置表作比对,

    2023年04月10日
    浏览(32)
  • Unity笔记:数据持久化的几种方式

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

    2024年02月19日
    浏览(31)
  • 【unity数据持久化】XML数据管理器知识点

    👨‍💻个人主页 :@元宇宙-秩沅 👨‍💻 hallo 欢迎 点赞👍 收藏⭐ 留言📝 加关注✅! 👨‍💻 本文由 秩沅 原创 👨‍💻 收录于专栏 :Unity基础实战 XML是什么 XML(Extensible Markup Language)是一种类似于 HTML,但是没有使用预定义标记的语言。因此,可以根据自己的设计需求

    2024年02月11日
    浏览(28)
  • 【unity数据持久化】数据管理类_PlayerPrfs封装包

    👨‍💻个人主页 :@元宇宙-秩沅 👨‍💻 hallo 欢迎 点赞👍 收藏⭐ 留言📝 加关注✅! 👨‍💻 本文由 秩沅 原创 👨‍💻 收录于专栏 : unity数据存储 🎶 PlayerPrefs—存储主方法 🎶 PlayerPrefs—普通数据类型的反射存储 🎶 PlayerPrefs—泛型List的反射存储 🎶 PlayerPrefs—泛型

    2024年02月12日
    浏览(26)
  • 【Redis7学习日记】—— Redis持久化

    Redis 的持久化是它的一大特性,可以将内存中的数据写入到硬盘中 主要分为 RDB 和 AOF 两种,接下来我们将展开叙述 RDB持久化方式能够在指定的时间间隔能对你的数据进行 快照 存储 AOF持久化方式记录每次对服务器写的操作,当服务器重启的时候会重新执行这些命令来恢复原始

    2023年04月09日
    浏览(33)
  • Unity3D学习之数据持久化——XML

    最终达到的效果 树形结构 属性通过空格隔开 属性名 = 引导包裹的内容 这两个代表的东西是一样的 可以在菜鸟上使用xml验证器 xml验证器 在Resources文件夹创建一个xml文件 把文件再复制到streamingAsserts 3.2.1 通过Resources文件进行读取 3.2.2 通过xml文件进行加载 获取根节点 遍历同名

    2024年01月23日
    浏览(34)
  • Unity3D学习之数据持久化——PlayerPrefs

    就是保存存档和读取存档。 分为两部分,存储和读取,先看存储在看读取 PlayerPrefs 是unity提供可以存储和读取玩家数据的公共类 上面定义过 PlayerPrefs.SetInt(“myAge”,18) 后面再定义PlayerPrefs.SetFloat(“myAge”,20.2f) 后面进行读取int型 myAge时,会变成默认值0 打印结果 0 和 100 1)父

    2024年01月18日
    浏览(66)

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

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

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

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

二维码1

领取红包

二维码2

领红包