当前位置: 首页 > 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…...

NJ求职盘点

电子显示 集成电路 地平线 后摩智能 芯启源 自动驾驶 地平线 栖霞区兴智科技园 泊车、SLAM/3D算法工程师 https://wecruit.hotjob.cn/SU64819a4f2f9d2433ba8b043a/pb/social.html?currentPage1 后摩智能 栖霞区兴智科技园 视觉感知算法资深工程师 可以做自动驾驶前瞻性…...

01卡特兰数

卡特兰数跟排列组合很有关系&#xff0c;所以在看此文章前请掌握&#xff1a; 加法原理乘法原理A(m,n)计算公式及其原理C(m,n)计算公式及其原理 前言 今天您将会学习到基本的卡特兰数及其应用。 一、卡特兰数是什么&#xff1f; 卡特兰数&#xff08;Catalan number&#xff0…...

若依前端vue设置子路径

若依前端vue设置子路径 说明&#xff1a;本文档中以前后端分离版为例&#xff0c;版本为:3.8.6 一设置变量 在.env.development和.env.production 中定义一个变量如VUE_APP_PROJECT_IDENTIFIER # 项目标识字符 VUE_APP_PROJECT_IDENTIFIER admin二引用路径变量 ${process…...

Vue中使用pdf.js实现在线预览pdf文件流

以下是在Vue中使用pdf.js实现在线预览pdf文件流的步骤&#xff1a; 1. 安装pdf.js npm install pdfjs-dist2. 引入pdf.js 在需要使用的组件中&#xff0c;使用以下代码引入pdf.js&#xff1a; import pdfjsLib from pdfjs-dist3. 加载pdf文件流 使用pdf.js的getDocument()方…...

态、势、感、知与时空、关系

态势感知是一种通过收集、整合、分析和解释大量的时空数据&#xff0c;以获取关于特定领域、地区或事件的全面理解的过程。时空和关系在态势感知中扮演着非常重要的角色。 态&#xff1a;态指的是物体或系统所处的状态或状况。在不同的态下&#xff0c;物体或系统的性质、行为和…...

D. Paths on the Tree

Problem - 1746D - Codeforces 思路&#xff1a;先分析一下题意&#xff0c;根据第一条性质&#xff0c;每次只能够从1开始&#xff0c;而第二条性质则表明对于每个节点来说&#xff0c;经过这个节点的子节点的路径条数应该尽量均衡&#xff0c;最大值与最小值相差不能超过1&am…...

CocosCreator3.8研究笔记(九)CocosCreator 场景资源的理解

相信很多朋友都想知道&#xff0c; Cocos Creator 资源的定义&#xff1f; Cocos Creator 常见的资源包含哪些&#xff1f;Cocos Creator 资源的管理机制是什么样的&#xff1f; Cocos Creator 中所有继承自 Asset 的类型都统称资源 &#xff0c;例如&#xff1a;Texture2D、Sp…...

大数据课程L1——网站流量项目的概述整体架构

文章作者邮箱:yugongshiye@sina.cn 地址:广东惠州 ▲ 本章节目的 ⚪ 了解网站流量项目的案例概述; ⚪ 了解网站流量项目的数据埋点和采集; ⚪ 了解网站流量项目的整体架构; 一、网站流量项目概述 1. 背景说明 网站流量统计是改进网站服务的重要手段之一…...

提升数据库安全小技巧,使用SSH配合开源DBeaver工具连接数据库

title: 提升数据库安全小技巧&#xff0c;使用SSH配合开源DBeaver工具连接数据库 categories: 独立博客的方方面面 前段时间, 未来降低网址运行成本&#xff0c;搭了一套Mysql Docker 数据库, 包括外部链接&#xff0c;数据备份&#xff0c;数据导出&#xff0c;数据恢复一套解…...

信息安全技术概论-李剑-持续更新

图片和细节来源于 用户 xiejava1018 一.概述 随着计算机网络技术的发展&#xff0c;与时代的变化&#xff0c;计算机病毒也经历了从早期的破坏为主到勒索钱财敲诈经济为主&#xff0c;破坏方式也多种多样&#xff0c;由早期的破坏网络到破坏硬件设备等等 &#xff0c;这也…...

java项目基于 SSM+JSP 的人事管理系统

java项目基于 SSMJSP 的人事管理系统 博主介绍&#xff1a;✌程序员徐师兄、7年大厂程序员经历。全网粉丝30W,Csdn博客专家、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ 大家好&#xff0c;今天和大家聊的是 Java 基于 SSM 的人事管理系统。…...

【Node.js】—基本知识点总结

【Node.js】—基本知识总结 一、命令行常用操作 二、Node.js注意点 Node.js中不能使用BOM和DOM操作 总结 三、Buffer buffer是一个类似于数组的对象&#xff0c;用于表示固定长度的字节序列buffer的本质是一段内存空间&#xff0c;专门用来处理二进制数据 特点&#xff1a;…...

Leetcode.174 地下城游戏

题目链接 Leetcode.174 地下城游戏 hard 题目描述 恶魔们抓住了公主并将她关在了地下城 d u n g e o n dungeon dungeon 的 右下角 。地下城是由 m x n 个房间组成的二维网格。我们英勇的骑士最初被安置在 左上角 的房间里&#xff0c;他必须穿过地下城并通过对抗恶魔来拯救公…...

python实现adb辅助点击屏幕工具

#!/usr/bin/env python # -*- coding: utf-8 -*-import re import os import time import subprocess import tkinter as tk from tkinter import messagebox from PIL import Image, ImageTk# 设置ADB路径&#xff08;根据你的系统和安装路径进行调整&#xff09; ADB_PATH C…...

智能合约安全分析,针对 ERC777 任意调用合约 Hook 攻击

智能合约安全分析&#xff0c;针对 ERC777 任意调用合约 Hook 攻击 Safful发现了一个有趣的错误&#xff0c;有可能成为一些 DeFi 项目的攻击媒介。这个错误尤其与著名的 ERC777 代币标准有关。此外&#xff0c;它不仅仅是众所周知的黑客中常见的简单的重入问题。 这篇文章对 …...

nodejs 爬虫 axios 异步爬虫 教程 【一】

axios 自定义headers axios.defaults.headers.common["User-Agent"] "Googlebot/2.1 (http://www.google.com/bot.html)"; 运行环境&#xff1a; node &#xff1a;v18 const axios require("axios"); axios.defaults.headers.common["U…...

Swift学习笔记三(Dictionary 篇)

1 Dictionary 概念 字典储存无序的互相关联的同一类型的键和同一类型的值的集合。字典类型的全写方式 Dictionary<Key, Value>&#xff0c;简写方式 [Key: Value]&#xff0c;建议使用简写方式。字典的 key 必须是可哈希的。 2 Dictionary创建 2.1 初始器创建方式 2.2 …...

javax.mail 遇到501 mail from address must be same as authorization user 的問題

使用不同的兩個帳戶发送email时&#xff0c;第一个账户可以发送成功&#xff0c;但到第二个账户的时候就报出了501 mail from address must be same as authorization user的错误。 具体代码如下&#xff1a; import java.util.Date; import java.util.List; import java.util.…...

【Python】网络编程

Socket Socket (简称 套接字)是进程之间通信一个工具&#xff0c;进程之间想要进行网络通信需要socket。Socket负责进程之间的网络数据传输&#xff0c;好比数据的搬运工。 客户端和服务端 2个进程之间通过Socket进行相互通讯&#xff0c;就必须有服务端和客户端 Socket服务…...

深入剖析AI大模型:大模型时代的 Prompt 工程全解析

今天聊的内容&#xff0c;我认为是AI开发里面非常重要的内容。它在AI开发里无处不在&#xff0c;当你对 AI 助手说 "用李白的风格写一首关于人工智能的诗"&#xff0c;或者让翻译模型 "将这段合同翻译成商务日语" 时&#xff0c;输入的这句话就是 Prompt。…...

java_网络服务相关_gateway_nacos_feign区别联系

1. spring-cloud-starter-gateway 作用&#xff1a;作为微服务架构的网关&#xff0c;统一入口&#xff0c;处理所有外部请求。 核心能力&#xff1a; 路由转发&#xff08;基于路径、服务名等&#xff09;过滤器&#xff08;鉴权、限流、日志、Header 处理&#xff09;支持负…...

shell脚本--常见案例

1、自动备份文件或目录 2、批量重命名文件 3、查找并删除指定名称的文件&#xff1a; 4、批量删除文件 5、查找并替换文件内容 6、批量创建文件 7、创建文件夹并移动文件 8、在文件夹中查找文件...

Swift 协议扩展精进之路:解决 CoreData 托管实体子类的类型不匹配问题(下)

概述 在 Swift 开发语言中&#xff0c;各位秃头小码农们可以充分利用语法本身所带来的便利去劈荆斩棘。我们还可以恣意利用泛型、协议关联类型和协议扩展来进一步简化和优化我们复杂的代码需求。 不过&#xff0c;在涉及到多个子类派生于基类进行多态模拟的场景下&#xff0c;…...

Python爬虫实战:研究feedparser库相关技术

1. 引言 1.1 研究背景与意义 在当今信息爆炸的时代,互联网上存在着海量的信息资源。RSS(Really Simple Syndication)作为一种标准化的信息聚合技术,被广泛用于网站内容的发布和订阅。通过 RSS,用户可以方便地获取网站更新的内容,而无需频繁访问各个网站。 然而,互联网…...

C++中string流知识详解和示例

一、概览与类体系 C 提供三种基于内存字符串的流&#xff0c;定义在 <sstream> 中&#xff1a; std::istringstream&#xff1a;输入流&#xff0c;从已有字符串中读取并解析。std::ostringstream&#xff1a;输出流&#xff0c;向内部缓冲区写入内容&#xff0c;最终取…...

BCS 2025|百度副总裁陈洋:智能体在安全领域的应用实践

6月5日&#xff0c;2025全球数字经济大会数字安全主论坛暨北京网络安全大会在国家会议中心隆重开幕。百度副总裁陈洋受邀出席&#xff0c;并作《智能体在安全领域的应用实践》主题演讲&#xff0c;分享了在智能体在安全领域的突破性实践。他指出&#xff0c;百度通过将安全能力…...

根据万维钢·精英日课6的内容,使用AI(2025)可以参考以下方法:

根据万维钢精英日课6的内容&#xff0c;使用AI&#xff08;2025&#xff09;可以参考以下方法&#xff1a; 四个洞见 模型已经比人聪明&#xff1a;以ChatGPT o3为代表的AI非常强大&#xff0c;能运用高级理论解释道理、引用最新学术论文&#xff0c;生成对顶尖科学家都有用的…...

【HarmonyOS 5 开发速记】如何获取用户信息(头像/昵称/手机号)

1.获取 authorizationCode&#xff1a; 2.利用 authorizationCode 获取 accessToken&#xff1a;文档中心 3.获取手机&#xff1a;文档中心 4.获取昵称头像&#xff1a;文档中心 首先创建 request 若要获取手机号&#xff0c;scope必填 phone&#xff0c;permissions 必填 …...

【数据分析】R版IntelliGenes用于生物标志物发现的可解释机器学习

禁止商业或二改转载&#xff0c;仅供自学使用&#xff0c;侵权必究&#xff0c;如需截取部分内容请后台联系作者! 文章目录 介绍流程步骤1. 输入数据2. 特征选择3. 模型训练4. I-Genes 评分计算5. 输出结果 IntelliGenesR 安装包1. 特征选择2. 模型训练和评估3. I-Genes 评分计…...