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

news2024/11/28 8:39:14

目录

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.json
        File.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://www.coloradmin.cn/o/1961618.html

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

相关文章

Echarts toolbox相关配置 dataZoom缩放

前言:最近开发遇到一个echarts相关问题,需要实现用户鼠标滚动实现图表缩放,或者实现选中某一段区域进行缩放,放大效果; 1.第一个需求就是区域缩放按钮要隐藏掉,用户鼠标放在图表内就默认实现选择效果,并且区域缩放还原按钮不能隐藏,需要在初始化配置这三个属性. // 假设你已经…

孙宇晨建议中国重新考虑“比特币政策”!中美竞争将使加密货币行业受益?美国对“中国崛起”感到焦虑!

近日&#xff0c;前美国总统特朗普发表了一番振奋人心的比特币演讲&#xff0c;令加密货币社群反响热烈。而Tron区块链创始人孙宇晨则建议中国重新考虑其对于比特币的政策立场&#xff0c;并指出中美两国在加密货币领域的竞争&#xff0c;将使整个行业受益。这再次引发了人们对…

未来社交:Facebook如何定义虚拟现实的新时代?

随着科技的飞速发展&#xff0c;虚拟现实&#xff08;VR&#xff09;逐渐从科幻小说中的幻想变成了现实生活中的前沿技术。在这一领域&#xff0c;Facebook&#xff08;现已更名为Meta&#xff09;扮演了重要角色&#xff0c;通过不断的创新和投资&#xff0c;致力于打造一个全…

花几千上万学习Java,真没必要!(三十六)

1、File类&#xff1a; 测试代码1&#xff1a; package filetest.com; import java.io.File; import java.io.IOException; public class FileOperations { public static void main(String[] args) { // 创建新文件File file new File("example.txt"); tr…

18966 两两配对差值最小

这个问题可以通过排序和配对来解决。首先&#xff0c;我们将数组排序&#xff0c;然后我们将数组的第一个元素和最后一个元素配对&#xff0c;第二个元素和倒数第二个元素配对&#xff0c;以此类推。这样&#xff0c;我们可以得到n/2个和&#xff0c;然后我们找出这些和中的最大…

光伏可行性研究报告能否自动生成?

随着技术的不断进步和应用的广泛普及&#xff0c;光伏项目的规划与实施也面临着更加复杂多变的考量因素&#xff0c;其中&#xff0c;光伏可行性研究报告成为了项目前期不可或缺的重要内容。那么&#xff0c;面对这一需求&#xff0c;光伏可行性研究报告能否实现自动生成呢&…

Nat Med·UNI:开启计算病理学新篇章的自监督基础模型|顶刊精析·24-07-31

小罗碎碎念 本期推文主题 这一期推文是病理AI基础模型UNI的详细介绍&#xff0c;原文如下。下期推文会介绍如何使用这个模型&#xff0c;为了你能看懂下期的推文&#xff0c;强烈建议你好好看看今天这期推文。 看完这篇推文以后&#xff0c;你大概就能清楚这个模型对自己的数据…

搞懂数据结构与Java实现

文章链接&#xff1a;搞懂数据结构与Java实现 (qq.com) 代码链接&#xff1a; Java实现数组模拟循环队列代码 (qq.com) Java实现数组模拟栈代码 (qq.com) Java实现链表代码 (qq.com) Java实现哈希表代码 (qq.com) Java实现二叉树代码 (qq.com) Java实现图代码 (qq.com)

《计算机网络》(第8版)考研真题

第一章 一、选择题 1 在 TCP/IP 体系结构中,直接为 ICMP 提供服务的协议是( )。[2012 年统考] A .PPP B .IP C .UDP D .TCP 【答案】B 【解析】A 项:PPP 在 TCP/IP 体系结构中属于网络接口层协议(在 ISO/OSI 体系结构中属于数据链路层协议),所以 PPP 为网络层提供…

免费【2024】springboot 厨房达人美食分享平台

博主介绍&#xff1a;✌CSDN新星计划导师、Java领域优质创作者、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和学生毕业项目实战,高校老师/讲师/同行前辈交流✌ 技术范围&#xff1a;SpringBoot、Vue、SSM、HTML、Jsp、PHP、Nodejs、Python、爬虫、数据可视化…

图片格式转换教程:百种格式随意转换,建议收藏使用!

图片格式转换方法有哪些&#xff1f;本文整理了几款好用且简单的格式转换工具&#xff0c;适用于处理各种图片格式转换的难题。 常见的图片格式转换有png转换为jpg、heic转jpg、webp转jpg等&#xff0c;特别是heic、webp、这两种图片格式&#xff0c;格式比较特殊&#xff0c;兼…

《最新出炉》系列入门篇-Python+Playwright自动化测试-57- 上传文件 - 番外篇

软件测试微信群&#xff1a;https://bbs.csdn.net/topics/618423372 有兴趣的可以扫码加入 1.简介 前边的三篇文章基本上对文件上传的知识介绍和讲解的差不多了&#xff0c;今天主要是来分享宏哥在文件上传的实际操作中发现的一个问题&#xff1a;input控件和非input控件的上…

打破技术壁垒,加速企业数字化转型:低代码平台如何降低开发门槛

科技飞速发展&#xff0c;企业数字化转型趋势不可逆转。数字化转型不仅能够优化内部运营流程&#xff0c;提升管理效率&#xff0c;还能通过数据驱动决策&#xff0c;增强市场竞争力。传统开发模式因技术门槛、周期长&#xff0c;限制了企业创新与响应速度。 低代码平台应运而生…

Android进阶之NDK开发,保姆级教程

目录 前言NDK下载CMake文件创建指定ABI架构编写CMake文件编写JNI方法Java调用CC调用Java 生成JNI头文件实现对应C方法编译so文件编写demo验证运行效果总结 前言 作为Android应用开发从业者来说&#xff0c;掌握NDK开发是必备技能之一&#xff0c;本文将从NDK环境下载&#xff…

Spring源码-xml配置文件如何加载解析默认标签变为BeanDefinition

1.创建Environment new StandardEnvironment() createEnvironment:346, AbstractApplicationContext (org.springframework.context.support) getEnvironment:332, AbstractApplicationContext (org.springframework.context.support) resolvePath:131, AbstractRefreshable…

通俗易懂理解提示词工程、RAG和微调

在当今的人工智能领域&#xff0c;提示工程、RAG&#xff08;检索增强生成&#xff09;和微调是三个重要的概念。本文将通过简单易懂的方式&#xff0c;帮助大家理解这三者之间的关系和应用。 大模型的训练过程 &#x1f4ca; 在当今的人工智能领域&#xff0c;大模型的训练是…

如何使用 Flask 或 Django 创建 Web 应用

Flask和Django是Python中最受欢迎的两个Web框架&#xff0c;它们各有优点&#xff0c;适用于不同的应用场景。 一、使用Flask创建Web应用 1.1 Flask简介 Flask是一个轻量级的Web框架&#xff0c;以其简洁、易用和灵活著称。它遵循“微框架”的设计理念&#xff0c;只提供核心…

批量输出文件夹内所有文件名和文件——vba实现

导出一个文件夹下所有文件名&#xff0c;可用vba插件实现&#xff0c;如图 如下图&#xff0c;已在桌面生成一个txt文本&#xff0c;但此方法只可输出一级目录下的文件&#xff0c;若输出所有文件&#xff0c;则需修改插件代码 &#xff08;若想导出硬盘下所有文件和文件夹&…

Windows10+VS2019编译Faiss

先放上我编译好的静态库&#xff0c;要配合OpenBLAS使用 通过百度网盘分享的文件&#xff1a;3rdparty.zip 链接&#xff1a;https://pan.baidu.com/s/1yPys-CX_EdmnJzj66g_KlQ?pwdh6ff 提取码&#xff1a;h6ff –来自百度网盘超级会员V1的分享 1.源码下载 首先下载Faiss地…

C++ STL inner_product 用法

一&#xff1a;功能 求内积&#xff0c; 给定两个向量x&#xff0c;y&#xff0c;内积公式如下&#xff1a; 二&#xff1a;用法 #include <iostream> #include <vector> #include <numeric>int main() {std::vector<int> height…