机械拆装-基于Unity-本地数据持久化

目录

1. 数据结构简介:数据的集合

  1.1 线性数据结构

  1.2 非线性数据结构

2. 对数据集合的操作:

3. 数据持久化

   3.1 数据的序列化存储

   3.2 JSON文件硬盘存储

   3.2.1 Json文件允许存储的数据类型

    3.2.2 Json文件的语法格式

  3.2.3 Json文件的读取

3.2.4 Json文件的反序列化

3.2.5 Json文件的序列化写入


  在场景运行过程中,会产生大量的数据,有些数据在场景切换或者游戏重启时需要一直保持,不能被销毁或者初始化,因此需要将数据保存在本地或服务器的硬盘中。比如游戏场景中,人物获取的财富、背包等数据;比如在拆装场景中,装配零件的编号、名称、3D模型等信息。

  我们在存储数据的过程中,需要一定的结构或格式,以方便对数据进行遍历和编辑。大部分程序语言定义的数据结构都有具体的类型定义,不过这里不展开分析数据结构,仅举例在实际项目中对数据进行持久化管理的方法和代码。

1. 数据结构简介:数据的集合

  数据结构基本分为两大类——线性、非线性数据结构

  1.1 线性数据结构

  主要有:数组(一维、多维)、线性表(顺序表、链表)、栈、队列、串、数组、文件。

  以线性表为例,其逻辑结构是n个数据元素的有限序列,所有数据元素曾线性关系,有唯一的“第一个”和“最后一个”数据元素,并且除“第一个”和“最后一个”数据元素外,每个元素有且只有一个前驱元素和一个后继元素。我们常用的List列表就是典型的线性表。

  

  1.2 非线性数据结构

  主要有:散列表(哈希表)、树、图。

  以哈希表为例,其存储数据的基本思想就是以结点的关键字为自变量,通过一定的函数关系(散列函数)计算出对应的函数值,以这个值作为该节点存储在散列表中的地址。哈希表使用节点关键字对应存储地址,查询效率高,并且可以由自己设定的函数关系来指定内存的存放规律。

2. 对数据集合的操作:

  不管是哪种数据类型,对于数据的操作需要基本有编辑(增、减、修改)、排序、统计、遍历等,操作算法比较著名的有冒泡、二分法、希尔、递归等。

  落地到unity的实际项目中,可以使用不同函数对不同类型的数据操作。比如最常见的列表List<T>,字典Dictionary<T, T>,常见的操作有读取数据、排序、新增数据、修改数据等,可以参考Unity开发之C#基础-列表(List)_unity list-CSDN博客 描述了对于List列表的常用操作。

3. 数据持久化

  以上介绍了数据的几种方式,那么如何将这些数据保存下来,而不随着场景切换和游戏的重启而消亡。目前常用的数据存储方式有:数据序列化存储内存存储、XML文件存储、JSON文件存储、数据库存储等多种形式。以下举例两种轻量化数据持久化方式:数据序列化存储、Json文本文件硬盘存储。

   3.1 数据的序列化存储

  使用System.Serializable属性序列化某个类的实例,让它可以被保存并能够在Inspector窗口中可视化和编辑,方便配置其属性,如图1所示(仅为示例,实际使用时请用英文字符作为变量名)。当数据或数据类型较多时,还可以嵌套使用,例如编写一个数据管理类来管理所有的数据实例,如图2所示。

    

  实现方法:

  (1)建立需要被保存的数据类,如果此数据项目较多,还可以使用CreateAssetMenu属性将这些数据列表放到菜单中,以方便反复建立。

  例如装配零件的功能,包括主轴、副轴、换挡拨叉、活塞曲柄等子装配体以及总体装配等多个装配模块,都需要记录零件的信息,那么就可以将零件信息作为一个数据类,然后建立列表管理零件信息,最后将列表建立在菜单中。代码如下:

using System;//需要调用
using System.Collections;
using System.Collections.Generic;
using UnityEngine;[Serializable]
//文件序列化
public class PartData
{//零件的信息类public int PartNo;public int AsblOrder;public String PartName;public GameObject PartObject;
}
[CreateAssetMenu(fileName = "PartData", menuName = "TangXiaoMo/PartData", order = 1)]
//将零件列表的创建放到菜单中,方便随时创建
public class PartDataConfig : ScriptableObject
{//零件的列表,记录所有零件的信息public int SceneNo;public List<PartData> PartList;
}

  (2)建立零件列表List<PartData>

   保存上面的代码后,我们在Assets随意位置都能创建零件的信息列表,如图所示:

  

  在这个零件列表文件中,可以在它的Inspector中配置我们所需要的零件信息。

  

  (3)数据修改及取用

   简单的方法,先定义一个公共的PartDataConfig变量,以便于在面板中拖入相应的数据文件:

public PartDataConfig _config;

  数据调用的方法如下,新建一个TestItem.cs文档:

public class TestItem : MonoBehaviour
{public PartDataConfig _config;private PartData _partData;void Start(){for (int i = 0; i < _config.PartList.Count; i++){//查询所有的零件名_partData = _config.PartList[i];Debug.Log(_config.PartList[i].PartName);}}
}

运行结果:

  数据修改的方法——对于列表中的数据直接赋值,代码举例如下:按K键修改主轴的装配顺序:

    void Update(){//修改数据if (Input.GetKeyDown(KeyCode.K))_config.PartList[0].AsblOrder = 10;//将装配顺序修改为10}

   3.2 JSON文件硬盘存储

  *.json文件是一种轻量级的数据交换格式,可以在多种编程语言中解析和使用,具有很强的可操作性。

   3.2.1 Json文件允许存储的数据类型

    数字型:short,int,long,float,double

    字符串:"abc"、"你好"、'abc'

    布尔:true false

    空类型:null

    数组、列表:[1,2,3]

    键值对:{"key1":{"id":01}} 

    3.2.2 Json文件的语法格式

    json文件以“键-值”对的形式存储,“键”和“值”之间使用冒号分隔;

    “键-值”对之间使用逗号分隔(最后一个“键-值”对后面不能写逗号);

    大括号{ }用于保存一个数据对象,支持大括号{ }嵌套;

    例如:

{"PartNo": 0,"AsblOrder": 0,"PartName": "01_主轴","PartPath": "PartPrefabs/01_主轴"
}

    如果要存储多个数据,例如前文中存储的多个零件信息的列表,也可以在Json文件中存为数组形式,用方括号[ ]包含,作为一个“值”,如:

{"partListID": 0,"partListName": "主轴零件","PartList": [{"PartNo": 0,"AsblOrder": 0,"PartName": "主轴","PartPath": "PartPrefabs/00_主轴"},{"PartNo": 1,"AsblOrder": 1,"PartName": "左1轴承","PartPath": "PartPrefabs/01_左1轴承"}]
}

    可以将上面的文字写在记事本中,后缀名保存为*.json,并且需保存为UFT-8格式编码

  3.2.3 Json文件的读取

  使用File.ReadAllText读取硬盘上的Json文件。将上面保存的Json文件命名为PartDataList.json,保存在Assets/StreamingAssets文件夹下,读取代码如下:

    // Json数据的读取void Start(){string str = System.IO.File.ReadAllText(Application.streamingAssetsPath + "/PartDataList.json");Debug.Log(str);}

    这里使用数据流函数Application设置硬盘读取路径,有以下几种类型的路径(windows系统、IOS和安卓系统的文件夹路径各不相同):

1. Application.dataPath               存储在Assets文件夹下(相对路径)
2. Application.streamingAssetsPath    存储在Assets/StreamingAssets下(相对路径)
3. Application.persistentDataPath     存储在C盘本地持久化存储路径(可读可写)
4. Application.temporaryCachePath     存储在C盘临时路径temp

    在本例中使用Application.streamingAssetsPath为读取路径,因此将PartDataList.json文件存储在Assets/StreamingAssets文件夹下。这时读取的数据没有被序列化,因此就是json源文件:

3.2.4 Json文件的反序列化

    使用JsonUtility解析方法,可以将Json文件的数据进行“内存->硬盘”和“硬盘->内存”的序列化和反序列化,这样可以将上面读取的混乱的信息存入相应的数据类型中。

  例如上面的零件信息Json文件——PartDataList.json,如果要将它从硬盘读取到内存,需要先建立对应的数据类,以便于将数据按类型存储到内存中,代码如下:

[Serializable]
public class PartInfo
{//零件信息数据public int PartNo;public int AsblOrder;public string PartName;public string PartPath;
}public class PartDataList
{//Json数据类public int partListID;public string partListName;public List<PartInfo> PartList;
}

   随后使用JsonUtility.FromJson<>将读取的字符串数据反序列化,并存入相应的数据类型中,代码如下:

public class TestGetJson : MonoBehaviour
{// 从Json文件中获取数据,并反序列化void Start(){string str;str = System.IO.File.ReadAllText(Application.streamingAssetsPath + "/PartDataList.json");PartDataList jsonData = JsonUtility.FromJson<PartDataList>(str);}
}

  在代码中打断点查看内存数据存储情况,从运行结果中可以看到,已将相应的int、string和List类型存入相应内存区域中:

3.2.5 Json文件的序列化写入

  可以使用JsonUtility方法在硬盘上新建一个Json文件,并存储上述的零件信息。代码如下:

//1. 先定义和序列化需要存储的数据类型
[Serializable]  //数据内容必须经过序列化才能使用JsonUtility.ToJson,否则不能完全显示
public class TestData
{//按照Json中的数据格式定义的数据类public int PartNo;      //零件号public int AsblOrder;   //装配顺序public string PartName; //零件名称public string PartPath; //零件模型的存放地址
}//2. 定义一个数据类,用于存放Json数据
public class TestJsonData
{public string name;  public List<TestData> dataList;public TestData data;}
//3. 使用JsonUtility写入Json文件
public class TestWriteJson : MonoBehaviour
{void Start(){string str;var testJson = new TestJsonData();  //新建一个数据对象testJson.name = "主轴零件列表";      //并初始化所有变量testJson.data = null;testJson.dataList = new List<TestData>(){new TestData(){PartNo = 0,AsblOrder = 1,PartName = "主轴",PartPath = "PartPrefabs/00_主轴"}};//使用JsonUtility.ToJson序列化以上对象,并返回一个字符串str = JsonUtility.ToJson(testJson);//文件写入一个新的Json文件-writeToJson.jsonFile.WriteAllText(Application.streamingAssetsPath+"/writeToJson.json",str);}}

  运行结果是在Assets/StreamingAssets文件夹下新建了一个writeToJson.json文件,文件内容如下。可以看到,虽然在初始化时,data变量赋值为null,但在实际运行时还是默认被赋了初值。

{"name":"主轴零件列表","dataList":[{"PartNo":0,"AsblOrder":1,"PartName":"主轴","PartPath":"PartPrefabs/00_主轴"}],"data":{"PartNo":0,"AsblOrder":0,"PartName":"","PartPath":""},"_private":1,"_protected":2}

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

如若内容造成侵权/违法违规/事实不符,请联系瞎胡闹网进行投诉反馈,一经查实,立即删除!

相关文章

【C#】ThreadPool的使用

1.Thread的使用 Thread的使用参考&#xff1a;【C#】Thread的使用 2.ThreadPool的使用 .NET Framework 和 .NET Core 提供了 System.Threading.ThreadPool 类来帮助开发者以一种高效的方式管理线程。ThreadPool 是一个线程池&#xff0c;它能够根据需要动态地分配和回收线程…

yolov8pose 部署rknn(rk3588)、部署地平线Horizon、部署TensorRT,部署工程难度小、模型推理速度快,DFL放后处理中

特别说明&#xff1a;参考官方开源的yolov8代码、瑞芯微官方文档、地平线的官方文档&#xff0c;如有侵权告知删&#xff0c;谢谢。 模型和完整仿真测试代码&#xff0c;放在github上参考链接 模型和代码。 之前写了yolov8、yolov8seg、yolov8obb 的 DFL 放在模型中和放在后处理…

XXE-lab-master靶场:PHP_xxe

目录 有回显 测试回显位置 构建payload 无回显数据外带 构建payload 漏洞修复 XXE-lab是一个一个包含php,java,python,C#等各种语言版本的XXE漏洞靶场。 下载地址&#xff1a;https://github.com/c0ny1/xxe-lab 将PHPStudy的中间件与版本信息调制为 php-5.4.29Apache 以…

UCC5320SCDWVR驱动SIC的功耗计算

驱动功耗可以通过分析器件的电气特性和推荐的电源电压来估算。以下是一些关键信息&#xff0c;用于估算功耗&#xff1a; 电源电流&#xff1a; 输入电源静态电流&#xff08;IVCC1​&#xff09;&#xff1a;最小值为1.67 mA&#xff0c;典型值为2.4 mA。输出电源静态电流&am…

计算机毕业设计选题推荐-零食批发商仓库管理系统-Java/Python项目实战

✨作者主页&#xff1a;IT研究室✨ 个人简介&#xff1a;曾从事计算机专业培训教学&#xff0c;擅长Java、Python、微信小程序、Golang、安卓Android等项目实战。接项目定制开发、代码讲解、答辩教学、文档编写、降重等。 ☑文末获取源码☑ 精彩专栏推荐⬇⬇⬇ Java项目 Python…

刷题了:226.翻转二叉树 | 101. 对称二叉树

226.翻转二叉树 文章讲解:https://programmercarl.com/0226.%E7%BF%BB%E8%BD%AC%E4%BA%8C%E5%8F%89%E6%A0%91.html 视频讲解:https://www.bilibili.com/video/BV1sP4y1f7q7/?spm_id_from333.788&vd_sourcee70917aa6392827d1ccc8d85e19e8375 题目链接:https://leetcode.cn…

从PyTorch官方的一篇教程说开去(5 - 神经网络 torch.nn)

神经网络长啥样&#xff1f;有没有四只眼睛八条腿&#xff1f; 借图镇楼 - 真的是非常经典&#xff0c;可以给下面的解释省掉很多力气。 分3个维度阐述 - 1&#xff09;输入数据集。假如你自己去微调一下大模型就知道&#xff0c;最开始的一步就是要准备&#xff08;足够大…

视频生成AI工具——PixVerse V2 登场:支持一键生成5段、最长 40S 连续视频!

就在昨天&#xff0c;光源伙伴 「 爱诗科技 」正式发布其视频生成产品 PixVerse V2 , 并全球同步开放&#xff0c;更低门槛&#xff0c;更高质量&#xff0c;更有逻辑&#xff0c;更长时长&#xff0c;这几个“更”&#xff0c;让这款产品受到了超高关注&#xff0c;今天带大家…

GD32手把手教你移植FlashDB(片外Flash) -- 3.FlashDB使用

GD32手把手教你移植FlashDB(片外Flash) – 1.FlashDB-sfud移植 GD32手把手教你移植FlashDB(片外Flash) – 2.FlashDB移植 GD32手把手教你移植FlashDB(片外Flash) – 3.FlashDB使用 示例代码: https://gitee.com/ljmRD/GD32F427_FlashDB 3.FlashDB使用 main() /*************…

华为云上如何创建桶

目录 一、进入对象存储服务(OBS)页面,点击【创建桶】二、输入桶的相关信息三、获取 projectId四、获取 OBS Endpoint五、获取 AK/SK一、进入对象存储服务(OBS)页面,点击【创建桶】 二、输入桶的相关信息 可以勾选购买套餐: 点【立即创建】按钮完成桶的创建。 三、获取…

Vue3开源Tree组件研发:节点勾选支持v-model

自研Tree组件有两个原因&#xff1a;1. 目前开源UI对Tree组件的用户API不太友好&#xff0c;2. 提升Vue3组件自研能力。 目前已实现的功能见上面思维导图。想象Tree组件的一个使用场景&#xff1a;后台管理员通过Tree组件来完成用户角色授权&#xff0c;同时支持对权限进行新增…

【和相同的二元子数组】python刷题记录

R2-前缀和专题 目录 前缀和哈希表 双指针 ps: 第一眼过去&#xff0c;这题应该能用双指针解出来&#xff0c;应该也能用前缀和解题。 前缀和哈希表 适用于 nums[i] 值不固定为 0 和 1 的其他情况 class Solution:def numSubarraysWithSum(self, nums: List[int], goal: i…

揭秘高效语音转文字工具:让沟通更便捷

嘿&#xff0c;各位办公室的小伙伴们&#xff0c;今儿咱们来聊聊那些能让咱们文员生活大变样的神器——特别是那些能把咱们嘴里嘟囔的话儿&#xff0c;瞬间变成电脑里整整齐齐文字的语音转文字工具。说起来&#xff0c;自从有了这些宝贝&#xff0c;我感觉自己都快能飞起来了&a…

onlyoffice用nginx反向代理

我对于onlyoffice的需求就是当个在线编辑器使用。在集成react的时候之前都是写的绝对路径的地址&#xff0c;这样在需要迁移应用的时候就造成了巨大的麻烦&#xff0c;所以我决定用nginx做反向代理&#xff0c;这样我集成的时候就不用每次都修改源码中的地址了。 一开始写的代…

ETH现货ETF流入量估算:会重演BTC现货ETF走势吗?

以太坊现货ETF将于7月23日上线&#xff0c;成为市场关注的焦点。ETH ETF的推出带来了很多与BTC ETF不同的特性&#xff0c;这些特性容易被市场忽视。本文将探讨ETH现货ETF的流入量估算&#xff0c;并分析其是否会重演BTC现货ETF的走势。 ETHE流出量预测 ETH ETF的收费结构与BT…

生活方式酒店升势迅起,喆啡酒店缘何成为投资热点?

伴随国内消费结构转型升级&#xff0c;旅游需求持续增加。文旅部发布的《国内旅游提升计划&#xff08;2023—2025年&#xff09;》提出&#xff0c;需丰富优质旅游供给&#xff0c;并进一步提高消费者体验及满意度&#xff0c;这将为酒店行业带来更广阔的客源和更高的质量要求…

云借阅图书管理系统——系统概述

一、云借阅系统功能模块介绍 云借阅图书管理系统主要实现了两大功能模块&#xff1a;用户登录模块和图书管理模块&#xff0c;用户登录模块主要用于实现用户的登录与注销&#xff1b;图书管理模块主要用于管理图书&#xff0c;如新书推荐、图书借阅等。 二、云借阅系统功能结…

怎么隐藏搜狗输入法

点击输入法&#xff0c;右键选择更多 点击选项&#xff0c;点击全屏隐藏

Mojo函数

正如在语言基础中提到的&#xff0c;Mojo支持两种类型的函数&#xff1a;def和fn函数。您可以在任何函数中使用这两种声明方式&#xff0c;包括main()函数&#xff0c;但它们具有不同的默认行为&#xff0c;如本页面所述。 我们认为def和fn都有很好的用例&#xff0c;并且不认…

opencv arm 交叉编译

step1.opencv源码文件夹下新建build-arm目录 step2. cmake图像化配置 cmake-gui .. step3. 选择交叉编译 step4.检索交叉编译链路径 step5. 配置 配置install路径 配置编译、链接选项 添加人脸检测模块 config->generate step6. make编译 built-arm目录下&#xff1a; …