当前位置: 首页 > news >正文

Unity——脚本序列化

在介绍序列化之前,我们先来了解一下为什么要对数据进行序列化

数据序列化有以下几个主要的应用场景和目的:

1. 持久化存储:序列化可以将对象或数据结构转换为字节序列,使得其可以被存储在磁盘上或数据库中。通过序列化,我们可以将应用程序中运行时的数据持久化保存,以便在后续运行时重新加载和使用。

2. 数据传输:序列化可以将对象转换为字节序列,以便在网络上进行传输。通过序列化,我们可以方便地将数据发送给远程服务器或其他系统,实现不同系统之间的数据交互和通信。

3. 数据缓存:序列化可以将对象存储在缓存中,以提高读取和访问的性能。通过序列化,我们可以将经常需要使用的数据对象序列化到缓存中,避免频繁地从数据库或其他存储介质中读取数据,从而提高应用程序的响应速度和效率。

4. 跨平台和版本兼容性:通过序列化,我们可以将对象转换为一种通用的数据格式,如 XML 或 JSON,使得数据在不同的平台和系统之间可以进行传递和解析。而且,序列化也留下了数据的结构信息,使得即使在对象结构发生变化或升级时,仍能够进行兼容性处理。

5. 调试和日志记录:在调试过程中,我们可以将对象的状态序列化为日志文件,以便后续查看和分析。通过序列化,我们可以捕获应用程序在某一特定时刻的状态,并将其存储下来,方便调试和故障排查。

总结来说,数据序列化可以使数据在不同的环境和系统中进行存储、传输和使用,以及提供持久化存储、数据交互、性能优化和兼容性处理等方面的好处。


一、序列化的概念

计算机硬盘中的文件只能保存纯数据,不能直接保存对象,网络传输亦是如此。在游戏存档、发送网络数据包的时候,都需要先将数据转化为纯粹的二进制数据,才能进行发送。反之,读取存档、接收数据包的时候,要进行相反的操作——把二进制数据转化为对象。

将对象转化为二进制数据的操作就叫做“序列化(Seriallize)”;相反的过程,将二进制数据转化为对象就叫做“反序列化(Deseriallize)”。

常用的序列化方案有以下几种:

  1. 自定义二进制序列化
  2. C#提供的序列化方案
  3. JSON
  4. XML
  5. ProtoBuf

1、自定义二进制序列化

自定义二进制序列化是一种在代码级别定义对象如何转换为二进制数据的过程,以及如何将二进制数据转换回对象。在Unity中,通过自定义二进制序列化,我们可以完全控制对象的序列化和反序列化过程,以适应特定的需求。

下面是一个简单的示例,演示如何自定义二进制序列化:


首先,我们需要为要序列化的对象创建一个自定义的数据结构。

[Serializable]
public class CustomData
{public int value1;public float value2;// ...
}

 然后,我们可以创建一个自定义的二进制序列化器。

public static class CustomSerializer
{public static byte[] Serialize(CustomData data){MemoryStream stream = new MemoryStream();BinaryWriter writer = new BinaryWriter(stream);// 将字段写入二进制流中writer.Write(data.value1);writer.Write(data.value2);// ...writer.Close();return stream.ToArray();}public static CustomData Deserialize(byte[] data){MemoryStream stream = new MemoryStream(data);BinaryReader reader = new BinaryReader(stream);CustomData customData = new CustomData();// 从二进制流中读取字段customData.value1 = reader.ReadInt32();customData.value2 = reader.ReadSingle();// ...reader.Close();return customData;}
}

最后,我们可以使用自定义的二进制序列化器来序列化和反序列化对象。

CustomData obj = new CustomData();
// 设置对象的值...byte[] serializedData = CustomSerializer.Serialize(obj);// 将二进制数据存储到磁盘或发送给其他系统...CustomData deserializedObj = CustomSerializer.Deserialize(serializedData);// 使用反序列化后的对象...

通过自定义二进制序列化,我们可以按需存储和传输对象的状态,或者与其他系统进行数据交换。在实际应用中,我们可能需要考虑字节顺序、对象版本控制、数据压缩等因素,以提高自定义二进制序列化的效率和可靠性。

2、C#提供的序列化方案

C# 提供了几种常用的序列化方案,用于将对象转换为字节序列并进行存储、传输或持久化。下面是一些常见的 C# 序列化方案:

1. 二进制序列化(Binary Serialization):
   C# 提供了 BinaryFormatter 类,可用于将对象序列化为二进制格式,并将其保存到文件或传输到其他地方。二进制序列化是一种简单而高效的方式,适用于需要快速序列化和反序列化的场景。但它的二进制数据不可读,也难以进行跨平台和版本兼容。

2. XML 序列化(XML Serialization):
   XML 序列化使用 `XmlSerializer` 类,将对象序列化成 XML 格式。XML 是一种自描述的格式,可读性较好,并具备跨平台和版本兼容性。通过 XML 序列化,我们可以将对象保存为 XML 文件,或将 XML 数据传输给其他系统。但 XML 格式会带来一定的性能开销,并且对于大型对象或复杂的数据结构,XML 格式可能会产生较大的文件大小。

3. JSON 序列化(JSON Serialization):
   C# 中的 JSON 序列化通过 `JsonSerializer` 类来实现。JSON(JavaScript Object Notation)是一种轻量级的数据交换格式,它具有可读性好、跨平台和版本兼容性,并且与 Web 开发密切相关。JSON 序列化可以将对象转换为 JSON 格式进行存储、传输和与其他系统进行数据交互。相对于 XML 格式,JSON 格式更加紧凑,但仍然具备很好的可读性。

4. Protobuf 序列化(Protocol Buffers Serialization):
   Protobuf 是 Google 发布的一种高效的二进制序列化格式,适用于跨平台和高性能的数据传输。在 C# 中,可以使用谷歌开源的 protobuf-net库进行 Protobuf 序列化。Protobuf 的优点包括高性能、小尺寸和协议版本兼容性,但其二进制数据不可读,需要定义数据的结构和消息格式。

这些序列化方案根据不同的需求和场景可以选择合适的方案。一般而言,二进制序列化适用于性能要求较高且不需进行数据查看的场景,XML 和 JSON 序列化适用于可读性好、跨平台和版本兼容性要求较高的场景,Protobuf 序列化适用于高性能和小尺寸的数据传输。

序列化的方案还有很多,也可以自己定义独特的序列化方案。理论上来说,只要能保存并正确读取数据的序列化方案都是合理的

二、简单存储PlayerPrefs

除了通用的序列化方法外,在很多游戏和应用程序中还需要保存一些简单的游戏偏好数据(Preference)。如音乐音量、音效音量、屏幕分辨率等,某些小游戏的最高分、游戏进度也可以用简单的方式保存在设备上。

Unity提供了PlayerPrefs,以满足保存简单数据的需求。它的共嗯比较单纯,用一个键(字符串类型)对应一个之,值的类型只支持整数、浮点数和字符串3种。PlayerPrefs不擅长保存复杂数据类型,其常用方法如下

当使用Unity进行游戏开发时,可以使用PlayerPrefs类来保存和访问玩家的偏好设置和游戏数据。

1、以下是一些PlayerPrefs的常用方法示例:

1. 设置偏好设置或游戏数据:

 PlayerPrefs.SetInt("HighScore", 100); // 设置整数值PlayerPrefs.SetFloat("Volume", 0.8f); // 设置浮点数值PlayerPrefs.SetString("PlayerName", "John"); // 设置字符串值

2. 获取偏好设置或游戏数据:

   int highScore = PlayerPrefs.GetInt("HighScore"); // 获取整数值float volume = PlayerPrefs.GetFloat("Volume"); // 获取浮点数值string playerName = PlayerPrefs.GetString("PlayerName"); // 获取字符串值

3. 检查是否存在特定键:

bool hasHighScore = PlayerPrefs.HasKey("HighScore"); // 检查是否存在HighScore键

4. 删除特定键的偏好设置或游戏数据:

 PlayerPrefs.DeleteKey("HighScore"); // 删除HighScore键的数据

5. 删除所有偏好设置或游戏数据:

PlayerPrefs.DeleteAll(); // 删除所有偏好设置和游戏数据

请注意,PlayerPrefs类用于存储简单的键值对数据,不适合存储大量复杂的游戏数据。对于大型游戏或复杂数据结构,应该考虑使用其他方法,如数据序列化和数据库。

2、应用实例

这里举一个能够在游戏退出时仍然保存数值的计数器

  1. 在场景中创建一个3D Text
  2. 默认的3D Text有点模糊,建议将Font Size设置为50,然后缩小Character Size为0.2(Font Size决定字符间隔大小,Character Size决定字体大小)
  3. 创建脚本TsetPrefs经挂到3D Text上
using System.Collections;
using System.Collections.Generic;
using UnityEngine;//这个写法的用途是强制物体具有TextMesh组件
[RequireComponent(typeof(TextMesh))]
public class TestPrefs : MonoBehaviour
{int counter = 0;TextMesh textMesh;void Start(){counter = PlayerPrefs.GetInt("counter");textMesh = GetComponent<TextMesh>();textMesh.text=counter.ToString();}// Update is called once per framevoid Update(){if(Input.GetButtonDown("Jump"))   //按空格加一{counter++;PlayerPrefs.SetInt("counter", counter);textMesh.text=counter.ToString();}if (Input.GetButtonDown("Cancel"))     //按Esc清零{counter=0;PlayerPrefs.SetInt("counter", counter);textMesh.text = counter.ToString();}}
}

完成之后就可以测试计数器效果了。运行游戏,按康哥可以让数字加1,按Esc数字清0.停止游戏后再次启动,数字会还原成上次退出时的值。

3、PlayerPrefs的实际保存位置

在Unity中,PlayerPrefs的实际保存位置取决于不同的操作系统。以下是不同操作系统上PlayerPrefs的实际保存位置:

1. Windows:
   PlayerPrefs数据在Windows系统中默认保存在注册表文件中。具体路径为:
   HKEY_CURRENT_USER\Software\[公司名]\[产品名]

2. macOS:
   PlayerPrefs数据在macOS系统中默认保存在plist文件中。具体路径为:
   ~/Library/Preferences/[公司名].[产品名].plist

3. Linux:
   在Linux系统中,PlayerPrefs数据默认保存在用户主目录的".config"目录下。具体路径为:
   ~/.config/unity3d/[公司名]/[产品名]/

4. iOS:
   在iOS设备上,PlayerPrefs数据会存储在应用的沙盒目录中。具体路径取决于应用的Bundle Identifier。

5. Android:
   在Android设备上,PlayerPrefs数据会存储在设备的Shared Preferences中,并根据应用的包名进行命名,并保存在应用的沙盒目录下。

需要注意的是,PlayerPrefs保存的数据是以明文形式存储的,因此不推荐将敏感或重要的数据直接保存在PlayerPrefs中。

相关文章:

Unity——脚本序列化

在介绍序列化之前&#xff0c;我们先来了解一下为什么要对数据进行序列化 数据序列化有以下几个主要的应用场景和目的&#xff1a; 1. 持久化存储&#xff1a;序列化可以将对象或数据结构转换为字节序列&#xff0c;使得其可以被存储在磁盘上或数据库中。通过序列化&#xff…...

es(Elasticsearch)介绍

学习es可以参考mysql&#xff08;相比mysql而言&#xff0c;es所需的cpu、内存更多&#xff09; 什么是Elasticsearch Elasticsearch简称es&#xff0c;是由Elastic和search组成。Elastic的意思是有弹性的&#xff0c;search的意思是搜索。 弹性&#xff1a;es是一个天生支持分…...

C++中使用 do…while 循环

C中使用 do…while 循环 在有些情况&#xff08;如程序清单 6.8 所示的情况&#xff09;下&#xff0c;您需要将代码放在循环中&#xff0c;并确保它们至少执行一次。此时 do…while 循环可派上用场。 do…while 循环的语法如下&#xff1a; do {StatementBlock; // executed…...

开源vue动态表单组件

一、项目简介 vueelement的动态表单组件&#xff0c;拖拽组件到面板即可实现一个表单 二、实现功能 支持拖拽 支持输入框 支持文本框 支持数字输入框 支持下拉选择器 支持多选框 支持日期控件 支持开关 支持动态表格 支持上传图片 支持上传文件 支持标签 支持ht…...

怎么从0到1创建一个PHP框架-1?

写在前面 本人开发的框架在2021年年初开发完成&#xff0c;后面没有再做过任何维护和修改。是仅供大家参考交流的学习项目&#xff0c;请勿使用在生产环境&#xff0c;也勿用作商业用途。 框架地址&#xff1a; https://github.com/yijiebaiyi/fast_framework 整体思路 开发…...

Qt无边框青绿色主题

收费产品&#xff0c;学生党、闹眼子党勿扰 收费金额&#xff1a;500元 1 概述 最近因项目需要&#xff0c;写了一个炫酷的青绿色、无边框界面&#xff0c;和3DSMax的界面有点类似。 2 截图 首先看看3DSMax的界面 不知道大家看出来没&#xff0c;这个ui其实很简单&#xff…...

200 套基于Java开发的Java毕业设计实战项目(含源码+说明文档)

文章目录 简介前言第一部分第二部分部分截图源码咨询 简介 博主介绍&#xff1a;✌程序员徐师兄、7年大厂程序员经历。全网粉丝30W、csdn博客专家、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ 前言 对于java方向的毕业设计题目选题&#xf…...

Ansible学习笔记7

user模块&#xff1a; user模块用于管理用户账户和用户属性。 如果是windows要换一个win_user模块。 创建用户&#xff1a;present&#xff1a; [rootlocalhost ~]# ansible group1 -m user -a "nameaaa statepresent" 192.168.17.106 | CHANGED > {"ansi…...

Python3 对列表、字典以及二者的嵌套数据(JSON)格式排序

在 Python 中&#xff0c;列表和字典都是基础数据类型&#xff0c;这两种数据类型会通过相互嵌套和多个层级形成复杂的数据类型&#xff0c;类似 JSON 数据格式&#xff0c;对列表和字典排序其实可以类比是对 JSON 排序。 列表排序 列表可以使用 sorted() 函数排序&#xff1…...

如何在B站进行学习直播

诸神缄默不语-个人CSDN博文目录 会根据我使用的情况进行持续更新 文章目录 1. 电脑 - 哔哩哔哩直播姬1. 软件的基础使用2. 素材1. 摄像头2. 窗口捕捉3. 游戏进程图片文字浏览器多媒体 3. H5插件其他注意事项 2. 手机直播3. iPad直播 1. 电脑 - 哔哩哔哩直播姬 1. 软件的基础使…...

老卫带你学---windows上安装minikube

老卫带你学—windows上安装minikube 1. 下载minikube https://storage.googleapis.com/minikube/releases/latest/minikube-installer.exe2.安装好后&#xff0c;将对应的目录添加env path 3. minikube start --kubernetes-versionv1.23.8 --image-mirror-countrycn...

Neo-reGeorg隧道搭建

目录 Neo-regeorg前言 环境搭建 具体使用 kail安装Neo-reGeorg kail内生成webshell并设置密码 kail与win10连接 windows server内打开服务 kail虚拟机访问windows server以及所在的内网 Neo-regeorg前言 regeorg为reDuh的升级版&#xff0c;主要功能就是把内网服务器的…...

Elasticsearch 7.6 - API高阶操作篇

ES 7.6 - API高阶操作篇 分片和副本索引别名添加别名查询所有别名删除别名使用别名代替索引操作代替插入代替查询 场景实操 滚动索引索引模板创建索引模板查看模板删除模板 场景实操一把索引的生命周期数据迁移APIGEO(地理)API索引准备矩形查询圆形查询多边形查询 自定义分词器…...

软件第三方验收测评介绍

软件第三方验收测试 软件项目验收测试介绍&#xff1a; 软件项目验收测试是部署软件之前的最后一个测试操作&#xff0c;是对系统进行全面的测试&#xff0c;以验证其是否符合合同要求&#xff0c;出具第三方测试报告&#xff0c;为系统验收提供依据。 验收测试的目的是&…...

HarmonyOS—使用Web组件加载页面

页面加载是 Web 组件的基本功能。根据页面加载数据来源可以分为三种常用场景&#xff0c;包括加载网络页面、加载本地页面、加载 HTML 格式的富文本数据。 页面加载过程中&#xff0c;若涉及网络资源获取&#xff0c;需要配置ohos.permission.INTERNET网络访问权限。 加载网络…...

Redis 缓存穿透、击穿、雪崩

一、缓存穿透 1、含义 缓存穿透是指查询一个缓存中和数据库中都不存在的数据&#xff0c;导致每次查询这条数据都会透过缓存&#xff0c;直接查库&#xff0c;最后返回空。 2、解决方案 1&#xff09;缓存空对象 就是当数据库中查不到数据的时候&#xff0c;我缓存一个空对象…...

设计模式-原型模式详解

文章目录 前言理论基础1. 原型模式定义2. 原型模式角色3. 原型模式工作过程4. 原型模式的优缺点 实战应用1. 原型模式适用场景2. 原型模式实现步骤3. 原型模式与单例模式的区别 原型模式的变体1. 带有原型管理器的原型模式2. 懒汉式单例模式的原型模式实现3. 细粒度原型模式 总…...

大语言模型之七- Llama-2单GPU微调SFT

&#xff08;T4 16G&#xff09;模型预训练colab脚本在github主页面。详见Finetuning_LLama_2_0_on_Colab_with_1_GPU.ipynb 在上一篇博客提到两种改进预训练模型性能的方法Retrieval-Augmented Generation (RAG) 或者 finetuning。本篇博客过一下模型微调。 微调&#xff1a…...

房地产行业专题报告:日本房地产市场借鉴

目录 1. 日本房地产泡沫的形成与崩溃 1.1 背景:实际需求减弱、宽松货币和弱金融监管推动泡沫形成 1.1.1 宏观环境:日本 80 年代起生育率降低,房地产基本面支撑力不足 1.1.2 货币政策:宽松货币政策叠加金融自由化促进泡沫生成 1.1.3 助推因素:企业积极参与土地投机、股…...

Educational Codeforces Round 154 (Rated for Div. 2)

Educational Codeforces Round 154 (Rated for Div. 2) A. Prime Deletion 思路&#xff1a; 因为1到9每个数字都有&#xff0c;所以随便判断也质素即可 代码 #include<bits/stdc.h> using namespace std; #define int long long #define rep(i,a,n) for(int ia;i<…...

Chapter03-Authentication vulnerabilities

文章目录 1. 身份验证简介1.1 What is authentication1.2 difference between authentication and authorization1.3 身份验证机制失效的原因1.4 身份验证机制失效的影响 2. 基于登录功能的漏洞2.1 密码爆破2.2 用户名枚举2.3 有缺陷的暴力破解防护2.3.1 如果用户登录尝试失败次…...

Flask RESTful 示例

目录 1. 环境准备2. 安装依赖3. 修改main.py4. 运行应用5. API使用示例获取所有任务获取单个任务创建新任务更新任务删除任务 中文乱码问题&#xff1a; 下面创建一个简单的Flask RESTful API示例。首先&#xff0c;我们需要创建环境&#xff0c;安装必要的依赖&#xff0c;然后…...

Prompt Tuning、P-Tuning、Prefix Tuning的区别

一、Prompt Tuning、P-Tuning、Prefix Tuning的区别 1. Prompt Tuning(提示调优) 核心思想:固定预训练模型参数,仅学习额外的连续提示向量(通常是嵌入层的一部分)。实现方式:在输入文本前添加可训练的连续向量(软提示),模型只更新这些提示参数。优势:参数量少(仅提…...

高等数学(下)题型笔记(八)空间解析几何与向量代数

目录 0 前言 1 向量的点乘 1.1 基本公式 1.2 例题 2 向量的叉乘 2.1 基础知识 2.2 例题 3 空间平面方程 3.1 基础知识 3.2 例题 4 空间直线方程 4.1 基础知识 4.2 例题 5 旋转曲面及其方程 5.1 基础知识 5.2 例题 6 空间曲面的法线与切平面 6.1 基础知识 6.2…...

生成 Git SSH 证书

&#x1f511; 1. ​​生成 SSH 密钥对​​ 在终端&#xff08;Windows 使用 Git Bash&#xff0c;Mac/Linux 使用 Terminal&#xff09;执行命令&#xff1a; ssh-keygen -t rsa -b 4096 -C "your_emailexample.com" ​​参数说明​​&#xff1a; -t rsa&#x…...

今日科技热点速览

&#x1f525; 今日科技热点速览 &#x1f3ae; 任天堂Switch 2 正式发售 任天堂新一代游戏主机 Switch 2 今日正式上线发售&#xff0c;主打更强图形性能与沉浸式体验&#xff0c;支持多模态交互&#xff0c;受到全球玩家热捧 。 &#x1f916; 人工智能持续突破 DeepSeek-R1&…...

NPOI Excel用OLE对象的形式插入文件附件以及插入图片

static void Main(string[] args) {XlsWithObjData();Console.WriteLine("输出完成"); }static void XlsWithObjData() {// 创建工作簿和单元格,只有HSSFWorkbook,XSSFWorkbook不可以HSSFWorkbook workbook new HSSFWorkbook();HSSFSheet sheet (HSSFSheet)workboo…...

PostgreSQL——环境搭建

一、Linux # 安装 PostgreSQL 15 仓库 sudo dnf install -y https://download.postgresql.org/pub/repos/yum/reporpms/EL-$(rpm -E %{rhel})-x86_64/pgdg-redhat-repo-latest.noarch.rpm# 安装之前先确认是否已经存在PostgreSQL rpm -qa | grep postgres# 如果存在&#xff0…...

数据库正常,但后端收不到数据原因及解决

从代码和日志来看&#xff0c;后端SQL查询确实返回了数据&#xff0c;但最终user对象却为null。这表明查询结果没有正确映射到User对象上。 在前后端分离&#xff0c;并且ai辅助开发的时候&#xff0c;很容易出现前后端变量名不一致情况&#xff0c;还不报错&#xff0c;只是单…...

结构化文件管理实战:实现目录自动创建与归类

手动操作容易因疲劳或疏忽导致命名错误、路径混乱等问题&#xff0c;进而引发后续程序异常。使用工具进行标准化操作&#xff0c;能有效降低出错概率。 需要快速整理大量文件的技术用户而言&#xff0c;这款工具提供了一种轻便高效的解决方案。程序体积仅有 156KB&#xff0c;…...