Unity——数据存储的几种方式

一、PlayerPrefs

PlayerPrefs适合用于存储简单的键值对数据

存储的数据会在游戏关闭后依然保持,并且可以在不同场景之间共享,适合用于需要在游戏不同场景之间传递和保持的数据。

它利用key-value的方式将数据保存到本地,跟字典类似。然后通过代码进行保存、读取、更新操作。值得注意的是此方法只能保存int型、float型,string型的数据,当然,对于bool类型的可以用0和1来代替真和假,以实现保存目的。

示例:制作登录界面的记住密码功能

1:在Start方法中判断PlayerPrefs是否存在该键名,有的话就设置

    private void Start(){if (PlayerPrefs.HasKey("Name")) {UserField.text = PlayerPrefs.GetString("Name");}if (PlayerPrefs.HasKey("Password")){PasswordField.text = PlayerPrefs.GetString("Password");}}

2:在登录按钮按下时,去设置该键值

 if(rememberToggle.isOn){PlayerPrefs.SetString("Name", UserField.text);PlayerPrefs.SetString("Password", PasswordField.text);}else{PlayerPrefs.DeleteKey("Password");}

PlayerPrefas就是这么简单,就是本地字典,可以离线存储

二、Json/Xml/Excel/Txt(本地)

1:Json
①书写解析类

需要创建和Json格式一样的类,以便于解析该Json文件到该类,不同复杂程度的Json文件,解析方式也不一样,简单的格式可以使用JsonUtility,复杂的则使用LitJson解析

比如Json格式如下:

{"name": "张三","level": 10,"hp": 100.0
}

解析类如下:

 public class PlayerData{public string name;public int level;public float hp;}

比如Json格式如下(嵌套格式):

{"name": "John","age": 30,"isStudent": true,"scores": [ 98, 95, 100 ],"address":{"city": "New York","state": "NY"}
}

解析类如下:

public class ExampleData
{public string name;public int age;public bool isStudent;public List<int> scores;public AddressData address;
}
public class AddressData
{public string city;public string state;
}

在Json的格式中,整块的内容需要用到{},数组的内容需要用到[]

②读取和解析Json文件

路径

string filePath = Application.streamingAssetsPath + "/JsonData/player.json";
string jsonString = File.ReadAllText(Application.streamingAssetsPath + "/JsonData/litexample.json");

第一种是文件的路径,第二种则直接把后面的读取该路径下的Json文件也包括了

解析

string jsonString = File.ReadAllText(filePath);
PlayerData playerData1 = JsonUtility.FromJson<PlayerData>(jsonString);
exampleData = JsonMapper.ToObject<ExampleData>(jsonString);

后续只需要对你读取到数据类中的数据进行读取就好了,当然这只是读取,还有存取,后续补

2:XML
①书写XML文件
<?xml version="1.0" encoding="UTF-8"?>
<library><book><title>Unity 3D游戏开发</title><authors><author>张三</author><author>李四</author></authors></book><book><title>Java编程思想</title><authors><author>John Doe</author><author>Jane Doe</author></authors></book>
</library>

<library> 是根元素(root element)。

  • <book> 元素包含了书的相关信息。
    • <title> 元素用于包含书的标题。
    • <authors> 元素用于包含一个或多个作者。
      • <author> 元素包含作者的名字。

标记的位置表明了层级关系,Library是最高层,就表明它是根节点元素,其次就是Book,Book是有两组,然后是Title和Authors是并列关系的,最后是两个Author

 <book>

 </book>


注意到这种结构,以尖括号不加/开始,以为尖括号加/结束!

②解析XML类
public class Book
{public string title;public List<string> authors = new List<string>();
}

解析类使用了XML中的最基础的Book数组

③解析方法

string filePath = Application.streamingAssetsPath + "/XMLData/XMLExample.xml";
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.Load(filePath);

XmlDocument是 .NET Framework 提供的 XML 文档处理类,允许你加载、创建、编辑和操作 XML 文档

//写成Static静态方法,可以在全局进行使用 
public static List<Book> ParseBooks(XmlDocument xmlDoc){//创建一个Book数组,用于存储数据List<Book> books = new List<Book>();//SelectSingleNode,获取XML的单一节点XmlNode root = xmlDoc.SelectSingleNode("library");//遍历该节点下的所有子节点foreach (XmlNode bookNode in root.ChildNodes){//再创建新的Book对象Book book = new Book();//再获取单一节点book.title = bookNode.SelectSingleNode("title").InnerText;XmlNode authorsNode = bookNode.SelectSingleNode("authors");foreach (XmlNode authorNode in authorsNode.ChildNodes){book.authors.Add(authorNode.InnerText);}books.Add(book);}return books;}

其实使用了xmlDoc.SelectSingleNode方法来选中XMl文件中的一个节点,然后再进行遍历,注意在遍历之前需要先创建对应的数据类进行存储
 

3:Excel

①导入读取文件

一般是EPPlus,Excel,ICharpCode,用于读取excle

②解析Excel

分成三步

//FileStream是基于IO名称空间
FileStream stream = File.Open(filePath, FileMode.Open, FileAccess.Read, FileShare.Read);//IExcelDataReader是基于Excel名称空间
IExcelDataReader excelReader = ExcelReaderFactory.CreateOpenXmlReader(stream);DataSet result = excelReader.AsDataSet();

第一步:

  • filePath:表示要打开的文件的路径。
  • FileMode.Open:表示以打开的方式打开文件,如果文件不存在则引发异常。
  • FileAccess.Read:表示以只读模式打开文件,不允许写入。
  • FileShare.Read:表示文件共享选项,允许多个读取器打开文件并同时读取。

第二步:

        创建一个 IExcelDataReader 对象,它用于读取 Excel 文件的内容ExcelReaderFactory.CreateOpenXmlReader 是从 ExcelDataReader 库中创建 Excel 读取器的工厂方法。这里使用的是 OpenXml 格式的读取器,它可以读取基于 Office Open XML 标准的 Excel 文件(.xlsx 格式)。

注意:     读取.xlsx格式的使用ExcelReaderFactory.CreateOpenXmlReader
                读取.xls格式的使用ExcelReaderFactory.CreateBinaryReader

第三步:

        读取 Excel 文件的内容,并将其转换为 DataSet 对象

③读取Excel
columnNum = result.Tables[0].Columns.Count;
rowNum = result.Tables[0].Rows.Count;

4:Txt

①获取路径

Resources:

string filePath = "MyTextFiles/Example.txt";

StreamingAssets:

string fileName = "Example.txt";
string filePath = Path.Combine(Application.streamingAssetsPath, fileName);
②读取文件
using System.IO;public string ReadTextFile(string filePath)
{try{if (File.Exists(filePath)){// 从文本文件中读取所有文本内容string content = File.ReadAllText(filePath);return content;}else{Debug.LogError("File not found: " + filePath);return null;}}catch (Exception e){Debug.LogError("Error reading text file: " + e.Message);return null;}
}

三、ScriptableObject

ScriptableObject是 Unity 提供的一个数据配置存储基类,它是一个可以用来保存大量数据的数据容器,我们可以将它保存为自定义的数据资源文件,实例会被保存成资源文件(.asset文件),和预制体,材质球,音频文件等类似,都是一种资源文件,存放在 Assets 文件夹下,创建出来的实例也是唯一存在的。

①创建目标数据结构的数据类

namespace Data
{public class Item{public string Name;public string Class;public string Sex;public string Age;}public class ItemManager : ScriptableObject{public Item[] dataArray;}
}

嵌套Item的数组

②编辑Scripts

可以在代码中进行编辑内容,也可以在外部进行编辑

public class ItemParser : MonoBehaviour
{public ItemManager itemManager; // 在Unity中分配你的ItemManager实例private void Start(){if (itemManager != null){// 遍历dataArray中的每个Item对象foreach (Item item in itemManager.dataArray){Debug.Log("Item Name: " + item.Name);Debug.Log("Item Class: " + item.Class);Debug.Log("Item Sex: " + item.Sex);Debug.Log("Item Age: " + item.Age);}}else{Debug.LogError("ItemManager is not assigned!");}}
}

③读取即可

四、数据库

一般使用数据库进行数据的增删改查,我的另一篇关于创建本地数据库的文章写的非常详细,详见:Unity_安装部署本地MySQL数据库(Navicat可视化)_mysql安装 unity_Future_404的博客-CSDN博客

1:SqlHelp

一般是工具方法,实现打开数据库,关闭数据库,增删改查等功能

  1. LeiSqlHelper 构造函数:接受数据库连接所需的参数(如主机地址、端口、用户名、密码、数据库名等),用于初始化数据库连接。

  2. Connect 方法:根据提供的连接信息来建立数据库连接。它将连接字符串创建并初始化了 MySqlConnection 对象。

  3. Open 方法:用于打开数据库连接。

  4. Close 方法:用于关闭数据库连接。

  5. Dispose 方法:用于在 using 块中释放资源,主要是调用 Close 方法。

  6. Select 方法:执行查询语句,允许你选择指定表的指定字段或选择整个表的所有字段,并返回一个包含结果的 DataSet。

  7. SelectWhere 方法:执行有条件的查询,你可以为查询指定条件,根据条件筛选数据,并返回一个包含结果的 DataSet。

  8. UpdateIntoSpecific 方法:执行更新操作,允许你根据条件更新指定表的特定字段。

  9. InsertInto 方法:执行插入操作,允许你向指定表插入数据。

  10. Delete 方法:执行删除操作,允许你删除符合条件的表中的数据或整个表的内容。

  11. CreateTable 方法:执行创建表的操作,允许你创建一个新的数据库表。

  12. ExecuteNonQuery 方法:执行 SQL 语句,通常用于更新、插入、删除等不返回数据集的操作。它返回受影响的行数。

2:SqlToos(读取)
using System.Collections.Generic;
using UnityEngine;
using Lei.Mysql;public class LeiTestSql : MonoBehaviour
{void Start(){//                                                      IP地址       端口   用户名    密码   数据库项目名称var mySqlTools = new LeiSqlHelper("127.0.0.1", "3306", "root", "123456", "SqlTest");//先打开数据库mySqlTools.Open();//创建表方法                          表名         字段名称                                            字段类型//mySqlTools.CreateTable("FirstData", new[] { "UID", "User", "Password" }, new[] { "tinytest", "tinytext", "tinytest" });//插入数据                      表名                     字段名称                                             插入的数据//mySqlTools.InsertInto("FirstData", new[] { "UID", "User", "Password" }, new[] { "雷康", "leikang", "123456" });//查询方法FindMysql(mySqlTools, "firstdata", new[] { "UID", "User", "Password" });//  插入方法                 表名                             字段名                                                 插入数据//mySqlTools.InsertInto("firstdata", new[] { "UID", "User", "Password" },new[] {"52022","ddxj1","123456" });//   更新方法                                     表名          更新字段名       判断符号          更新数据               查询条件字段         条件成立字段//mySqlTools.UpdateIntoSpecific("firstdata", new[] { "User" }, new[] { "=" }, new[] { "ddxj1" }, new[] { "Password" }, new[] { "456789" });//  删除方法                     表名          删除字段        判断条件       条件成立数据         //mySqlTools.Delete("firstdata", new[] { "User" }, new[] { "=" }, new[] { "ddxj1" });//查询方法                                               表名        查询字段名         判断字段名       判断符号        条件成立数据// var ds = mySqlTools.SelectWhere("firstdata", new[] { "UID" }, new[] { "User" }, new[] { "=" }, new[] { "ddxj1" });//查询方法                                              表名         判断字段名       判断符号        条件成立数据// var ds = mySqlTools.SelectWhere("firstdata", new[] { "User" }, new[] { "=" }, new[] { "ddxj1" });mySqlTools.Close();}/// <summary>/// 查询表中数据   记得先调用Open()方法  用完此方法后直接Close()/// </summary>/// <param name="mySqlTools">Mysql框架类</param>/// <param name="tableName">表名</param>/// <param name="items">字段名称</param>void FindMysql(LeiSqlHelper mySqlTools, string tableName, string[] items){var ds = mySqlTools.Select(tableName, items);//调取获取数据的方法var pairs = LeiSqlTools.TableData(ds);DebugMysql(pairs);}/// <summary>/// 打印查询数据库/// </summary>/// <param name="pairs"></param>private void DebugMysql(Dictionary<string, object>[] pairs){for (int i = 0; i < pairs.Length; i++){foreach (var table in pairs[i]){string tableList = string.Format("第{0}行,表字段名对应数据是 {1}", i + 1, table);print(tableList);}}}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/107949.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

ADAS可视化系统,让自动驾驶更简单 -- 入门篇

随着车载芯片的升级、技术的更新迭代&#xff0c;可视化ADAS逐渐变成汽车的标配走入大家的生活中&#xff0c;为大家的驾车出行带来切实的便捷。那么你了解HMI端ADAS的实现过程吗&#xff1f;作为ADAS可视化系统的入门篇&#xff0c;就跟大家聊一聊目前较常见的低消耗的一种ADA…

typora主题切换与推荐主题

在这篇博文中&#xff0c;我将向你展示如何给typora更换主题&#xff0c;并推荐几款出色的主题。通过这些主题的使用&#xff0c;你可以为你的typora编辑器增添一抹别样的风采&#xff0c;让你的写作体验更加美好、舒适。 typora替换主题的步骤非常简单&#xff0c;只需按照以…

C语言 形参、实参

定义 形参 形式上的参数&#xff0c;没有确定的值 实参 实际存在的&#xff0c;已经确定的参数&#xff0c;常量&#xff0c;变量&#xff0c;表达式&#xff0c;都是实参 区别 实参的值不随形参的变化而变化 在C语言中&#xff0c;数据传送是单向的&#xff0c;即只能把实…

【日常业务开发】接口性能优化

【日常业务开发】接口性能优化 缓存本地缓存分布式缓存 数据库分库分表SQL 优化 业务程序并行化异步化池化技术预先计算事务粒度批量读写锁的粒度尽快return上下文传递空间换时间集合空间大小 缓存 本地缓存 本地缓存&#xff0c;最大的优点是应用和cache同一个进程内部&…

怎么使用动态代理IP提升网络安全,动态代理IP有哪些好处呢

随着互联网的普及和数字化时代的到来&#xff0c;网络安全问题越来越受到人们的关注。动态代理IP作为网络安全中的一种技术手段&#xff0c;被越来越多的人所采用。本文将介绍动态代理IP的概念、优势以及如何应用它来提升网络安全。 一、动态代理IP的概念 动态代理IP是指使用代…

docker的资源限制参数设置错误,导致的clickhouse性能瓶颈

文章目录 使用场景问题现象解决处理 使用场景 我们使用docker作为服务的虚拟化工具&#xff0c;服务都部署在docker里我们使用docker-compose管理所有docker服务的配置文件针对某些服务&#xff0c;我们要限制这个docker服务容器占用的资源数量&#xff0c;例如cpu和内存在进行…

IPv6知识概述 - ND协议

IPv6知识概述 - ND协议 参考文章&#xff1a;https://blog.csdn.net/Gina_wj/article/details/106708770 IPv6基础篇&#xff08;四&#xff09;&#xff1a;邻居发现协议NDP ND协议功能概述 ND&#xff08;Neighbor Discovery&#xff0c;邻居发现&#xff09;协议是IPv6的…

flutter开发实战-下拉刷新与上拉加载更多实现

flutter开发实战-下拉刷新与上拉加载更多实现 在开发中经常遇到列表需要下拉刷新与上拉加载更多&#xff0c;这里使用EasyRefresh&#xff0c;版本是3.3.21 一、什么是EasyRefresh EasyRefresh可以在Flutter应用程序上轻松实现下拉刷新和上拉加载。它几乎支持所有Flutter Sc…

ICMP协议(二)

一 ping工作原理 ① 为什么ping不通 "ping不通分为两类" 1) 请求没有到目标服务器细节&#xff1a; 要注意是ip不通还是域名不能解析导致ping不通2) 请求到了目标服务器,但是没有回包 "常见原因" 1、对方关机/ip不存在备注&#xff1a; ping同网段不…

记一次MySQL5初始化被kill的问题排查 | 京东云技术团队

写在前面 由于测试环境JED申请比较繁琐&#xff0c;所以Eone提供了单机版Mysql供用户使用&#xff0c;近期Eone搭建Mysql5的时候发现莫名被kill了&#xff0c;容器规格是4C8G&#xff0c;磁盘30G 这不科学&#xff0c;之前都是可以的&#xff0c;镜像没变&#xff0c;配置没变…

k8s-16 k8s调度

调度器通过 kubernetes 的 watch 机制来发现集群中新创建且尚未被调度到 Node上的 Pod。调度器会将发现的每一个未调度的 Pod 调度到一个合适的 Node 上来运行。 kube-scheduler 是 Kubernetes 集群的默认调度器&#xff0c;并且是集群控制面的一部分如果你真的希望或者有这方面…

企业立案信息API的优势与应用场景

引言 随着科技的不断进步&#xff0c;创业者和企业家们在创办新企业时愈发依赖数字化工具。其中&#xff0c;企业立案信息API成为了一项重要的资源&#xff0c;它提供了有关企业立案的关键信息&#xff0c;为企业家们提供了许多优势和丰富的应用场景。本文将探讨企业立案信息A…

MybatisPlus多表关联分页返回结果异常

1. 按照该博客进行多表关联分页查询&#xff1a; https://blog.csdn.net/code_ang/article/details/116448694 2.在实际测试过程中&#xff0c;发现异常&#xff0c;分页返回的结果时而正确&#xff0c;时而错误。 count函数满足预期 count函数不满足预期 只是count了主表的…

竞赛 深度学习YOLOv5车辆颜色识别检测 - python opencv

文章目录 1 前言2 实现效果3 CNN卷积神经网络4 Yolov56 数据集处理及模型训练5 最后 1 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 &#x1f6a9; **基于深度学习YOLOv5车辆颜色识别检测 ** 该项目较为新颖&#xff0c;适合作为竞赛课题方向&#xff0…

C++之基于Winsock2封装UDPServer与UDPClient

文章目录 Socket过程UDPServer.hUDPServer.cppUDPClient.hUDPClient.cppmain.cppCMakeLists.txt测试截图 Socket过程 UDPServer UDPClient UDPServer.h #ifndef UDPSERVER_H_INCLUDED #define UDPSERVER_H_INCLUDED#include <iostream> #include <string> #inclu…

SAP-FI模块 处理自动生成会计凭证增强

2、固定资产业务过渡科目摘要增强功能-MIGO ENHANCEMENT 2 ZEHENC_SAPMF05A. "active version * FI 20221215&#xff1a;固定资产业务过渡科目摘要增强功能 WAIT UP TO 1 SECONDS.READ TABLE xbseg WITH KEY hkont 1601990001. IF sy-subrc 0.DATA: lt_bkdf TYPE …

flink教程

文章目录 来自于尚硅谷教程1. Flink概述1.1 特点1.2 与SparkStreaming对比 2. Flink部署2.1 集群角色2.2 部署模式2.3 Standalone运行模式2.3.1 本地会话模式部署2.3.2 应用模式 2.4 YARN运行模式2.4.1 会话模式部署2.4.2 应用模式部署 2.5 历史服务 3. 系统架构3.1 并行度3.2 …

【C++】缺省参数与函数重载

&#x1f440;樊梓慕&#xff1a;个人主页 &#x1f3a5;个人专栏&#xff1a;《C语言》《数据结构》《蓝桥杯试题》《LeetCode刷题笔记》《实训项目》《C》 &#x1f31d;每一个不曾起舞的日子&#xff0c;都是对生命的辜负 前言 本篇文章博主将带你学习缺省参数与函数重载&…

.Net Core 6 运行环境手动安装流程

安装.NET Core 6 概述 在开始之前&#xff0c;我们首先需要了解一下整个安装过程的流程。下面的表格将展示安装.NET Core 6的步骤以及每一步需要做的事情。 步骤 动作 说明 1 下载.NET Core 6 SDK 从官方网站下载.NET Core 6 SDK安装包 2 安装.NET Core 6 SDK …

win10如何取消文件夹分组

问题描述 最近不知道把哪里碰了&#xff0c;win10文件夹显示的文件都是按照日期分组了&#xff0c;很讨厌。如下图所示 修改方法 1、文件夹空白处-右击 2、分组依据(P)-选择(无)(N) 下面是操作好之后的效果图 结束 -----华丽的分割线&#xff0c;以下是凑字数&#xff0c;大…