Unity保存玩家的数据到文件中(Unity的二进制序列化)

文章目录

  • 文章运行环境
  • 什么是二进制序列化
  • 读写文件
    • 构造函数
  • 自定义二进制序列化

文章运行环境

Unity2022

什么是二进制序列化

Unity中的二进制序列化是一种将游戏对象或数据结构转换为二进制格式的过程,以便于存储或网络传输。这使数据能够以高效的方式保存,同时在需要时可以被正确地恢复(反序列化)回原始状态。二进制序列化对于保存游戏进度、网络同步数据或资源打包(如AssetBundles)特别有用。

二进制序列化通常比文本格式(如JSON、XML)更快,占用空间更小,但可能不如文本格式易于调试或跨平台兼容。

读写文件

在C#中,我们用FileStream类来读取、写入文件。它允许程序以流的形式访问文件系统中的文件,支持读取、写入、追加等多种操作模式。

FileStream类是.NET框架中一个非常核心的类,它位于System.IO命名空间下。

我们先来看一行代码,感受一下FileStream类读写文件的操作:

using FileStream stream = new FileStream(filePath, FileMode.Create);

这段代码创建了一个新的FileStream对象,用于与文件系统交互。这里有几个关键点:

new FileStream(filePath, FileMode.Create) 这里调用了FileStream的构造函数,它接受两个主要参数:

  • filePath: 字符串类型,表示要打开或创建的文件路径。如果路径不包含驱动器字母,它会被视为相对于当前工作目录的路径。
  • FileMode.Create: FileMode枚举的一个成员,指定了打开或创建文件的模式。在这个例子中我们用的是Create模式,表示如果指定的文件已经存在,则会覆盖现有文件(即删除原文件内容并开始写入新数据)。如果文件不存在,则会创建一个新文件。

另外示例使用了using语句,using关键字在这里用于确保FileStream对象在不再需要时(比如方法执行完毕或作用域结束)能够被正确且及时地关闭和释放相关资源。这有助于防止文件句柄泄露,保证系统资源的有效管理。使用using块可以自动调用Dispose()方法,即使在发生异常的情况下也能确保资源的释放。

构造函数

FileStream类提供了多个构造函数,以适应不同的使用场景。最基本的构造函数如下:

public FileStream(string path, FileMode mode);

其中,path是文件的路径,前面已经说的很详细了,这里不多赘述,mode决定了如何打开或创建文件,它是一个FileMode枚举值。除了FileMode.Create(如之前提到的,用于创建新文件或覆盖现有文件),还有其他几种模式,包括:

  • FileMode.Open:打开现有文件,如果文件不存在则抛出异常。
  • FileMode.OpenOrCreate:如果文件存在则打开,否则创建新文件。
  • FileMode.Append:打开文件以追加内容,如果文件不存在则创建新文件。
    当然还有其他模式,这里不多说了,大家可以查阅文档。

除了上述基本构造函数外,还有其他构造函数,例如可以通过额外的参数指定文件访问权限(如FileAccess.ReadWrite)、文件共享选项(FileShare.None, FileShare.Read, 等)以及文件选项(如FileOptions.Asynchronous)。这里暂不展开。

自定义二进制序列化

我们可以使用BinaryFormatter来实现更复杂的自定义序列化需求,虽然不是Unity引擎直接推荐的方法。

这个类是.NET的,完全限定名是System.Runtime.Serialization.Formatters.Binary.BinaryFormatter,我们用这个类来进行二进制序列化。这种方法允许你精细控制哪些数据被序列化,并且可以将数据写入到文件或内存流中。

接下来我们写一个例子来学习。首先,定义一个简单的PlayerData类,该类标记有[Serializable]属性,这样BinaryFormatter就能识别并处理它:

[Serializable]
public class PlayerData
{public string playerName;public int score;public DateTime lastPlayed;public PlayerData(string name, int score, DateTime time){this.playerName = name;this.score = score;this.lastPlayed = time;}
}

接下来,使用BinaryFormatter进行序列化和反序列化:

using System;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
using UnityEngine;
public class DataSaver : MonoBehaviour
{// Start is called before the first frame updatevoid Start(){// 创建一个示例对象PlayerData data = new("玩家1", 1000, DateTime.Now);// 序列化对象到文件SaveToFile(data, "game.save");// 从文件反序列化对象PlayerData loadedData = LoadFromFile("game.save");// 打印加载的数据,验证是否保存成功Debug.Log($"玩家名: {loadedData.playerName}");Debug.Log($"分数: {loadedData.score}");Debug.Log($"上次游玩时间: {loadedData.lastPlayed}");}static void SaveToFile(PlayerData data, string filePath){using FileStream stream = new(filePath, FileMode.Create);BinaryFormatter formatter = new();formatter.Serialize(stream, data);}static PlayerData LoadFromFile(string filePath){if (File.Exists(filePath)){using FileStream stream = new(filePath, FileMode.Open);BinaryFormatter formatter = new();return (PlayerData)formatter.Deserialize(stream);}else{throw new FileNotFoundException($"文件没找到: {filePath}");}}
}

在场景内创建一个物体,命名为DataSaver,然后将脚本挂载在该物体上。
在这里插入图片描述
运行程序,观察控制台
在这里插入图片描述

需要注意的是,当序列化数据结构发生变化时,需要考虑向前和向后兼容问题,确保旧数据能被正确反序列化,或提供数据迁移策略。

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

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

相关文章

富唯智能推出的AMR复合机器人铝板CNC上下料方案

随着科技的不断进步,CNC加工行业正面临着前所未有的变革。传统的CNC上下料方式已无法满足现代生产对效率、精度和安全性的高要求。在这样的背景下,富唯智能推出的AMR复合机器人铝板CNC上下料方案,以其智能化、自动化的特点,引领了…

Mind+在线图形编程软件(Sractch类软件)

Scratch作为图形编程软件,可以为小朋友学习编程提供很好的入门,是初次接触编程的小朋友的首选开发软件。这里介绍的Mind软件与Sractch用法几乎完全一致,并且可以提供在线免安装版本使用,浏览器直接打开网址: ide.mindp…

LeetCode.32最长有效括号详解

问题描述 给你一个只包含 ( 和 ) 的字符串,找出最长有效(格式正确且连续)括号子串的长度。 解题思路1 有效的括号字符串意味着每一个左括号 ( 都可以找到一个相匹配的右括号 )。栈可以帮助我们追踪尚未匹配的括号,并有效地处理…

Micro-ROS是什么?

Micro-ROS是ROS(Robot Operating System,机器人操作系统)生态系统的一个重要组成部分,专为微控制器(Microcontrollers)设计的轻量级ROS版本。它的目标是在资源有限的嵌入式平台上实现ROS 2的功能&#xff0…

RocketMQ:日常开发中有哪些使用MQ的场景

什么是消息队列? 消息队列是一种通信方法,允许应用程序通过发送和接收消息来互相通信。这些消息/任务/指令存储在一个中间介质中(即队列),并由生产者发送,消费者接收。 使用场景 场景一:任务…

昇思25天学习打卡营第1天|基本介绍

MindSpore 基本介绍设计理念层次结构 基本介绍 昇思MindSpore是一个全场景深度学习框架,旨在实现易开发、高效执行、全场景统一部署三大目标。 易开发:API友好、调试难度低高效执行:包括计算效率、数据预处理效率和分布式训练效率全场景&am…

手写SpringMVC之ApplicationContextListener

什么是Spring MVC? Spring Web MVC是基于Servlet API构建的原始Web框架,从一开始就包含在Spring Framework中。正式名称“Spring Web MVC”来自其源模块的名称( spring-webmvc ),但它通常被称为“Spring MVC”。 手写…

【python】OpenCV—Color Map

文章目录 cv2.applyColorMapcv2.putText小试牛刀自定义颜色 参考学习来自 OpenCV基础(21)使用 OpenCV 中的applyColorMap实现伪着色 cv2.applyColorMap cv2.applyColorMap() 是 OpenCV 中的一个函数,用于将灰度图像或单通道图像应用一个颜色…

The First Descendant卡顿怎么办?快速处理第一后裔卡顿

第一后裔/The First Descendant是一款刷宝类RPG射击游戏,以虚幻引擎5为基础,使其对决场景十分精彩、刺激,从而吸引了大批冒险者前往,这里揭开属于英格里斯和继承者的秘密。不过有很多玩家,反馈在对局时遇到了卡顿、画面…

Ubuntu 20.04.3 LTS 安装打印服务器 局域网发现系统服务 共享给 windows 10/11 使用

ubuntu安装部署打印服务器可参考: Ubuntu 20.04.3 LTS 安装hp 1020 plus 打印机 通过cups共享给 windows 10/11 使用-CSDN博客 1 windows 10 ,局域网搜索不到共享的hp1020打印机 2 Ubuntu使用Avahi进行局域网服务发现和设备发现,安装avahi-daemon sudo apt-updat…

【Linux】Linux下使用套接字进行网络编程

🔥博客主页: 我要成为C领域大神🎥系列专栏:【C核心编程】 【计算机网络】 【Linux编程】 【操作系统】 ❤️感谢大家点赞👍收藏⭐评论✍️ 本博客致力于知识分享,与更多的人进行学习交流 ​ 用于网络应用开…

Java基础(四)——字符串、StringBuffer、StringBuilder、StringJoiner

个人简介 👀个人主页: 前端杂货铺 ⚡开源项目: rich-vue3 (基于 Vue3 TS Pinia Element Plus Spring全家桶 MySQL) 🙋‍♂️学习方向: 主攻前端方向,正逐渐往全干发展 &#x1…

【技巧】如何检查多个GPU之间是否支持P2P通信

转载请注明出处:小锋学长生活大爆炸[xfxuezhagn.cn] 如果本文帮助到了你,欢迎[点赞、收藏、关注]哦~ 需要用到cuda_samples:GitHub - NVIDIA/cuda-samples 该工具的详细解释可以看这个: 【知识】详细介绍 CUDA Samples 示例工程…

不止是只有维度建模,数据仓库还有Data Vault建模

引言 在数据仓库设计中,传统的星型和雪花型模型有着各自的优势和劣势。随着数据量的增大和数据源的多样化,Data Vault(数据仓库)建模方法逐渐受到关注和应用。Data Vault建模是一种灵活、可扩展、适应性强的建模方法,…

Java知识点整理 12 — 前端 Ant Design Pro 初始化模板使用

一. 项目初始化 Ant Design Pro 是基于 Ant Design 和 umi 封装的一整套企业级中后台前端设计框架,致力于在设计规范和基本组件的基础上,继续向上构建,提炼出典型模板或配套设计资源,进一步提升企业级中后台产品设计研发过程中的…

用MySQL和navicatpremium做一个项目—(财务管理系统)。

1 ER图缩小的话怕你们看不清,所以截了两张图 2 vsdx绘图结果 3DDL和DML,都有点长分了好多次上传,慢慢看 DDL -- 用户表 CREATE TABLE users (user_id INT AUTO_INCREMENT PRIMARY KEY COMMENT 用户ID,username VARCHAR(50) NOT NULL UNIQUE COMMENT 用…

SpringCloud分布式微服务链路追踪方案:Skywalking

一、引言 随着微服务架构的广泛应用,系统的复杂性也随之增加。在这种复杂的系统中,应用通常由多个相互独立的服务组成,每个服务可能分布在不同的主机上。微服务架构虽然提高了系统的灵活性和可扩展性,但也带来了新的挑战&#xf…

vue的学习--day2

如有错误,烦请指正~ 目录 一、什么是单页面应用程序 二、使用工具:node.js 三、工具链 易错点 一、什么是单页面应用程序 多个组件(例如登录、注册等以vue结尾的都叫做组件)在一个页面显示,叫单页面应用…

【软件测试】白盒测试与接口测试详解

🍅 视频学习:文末有免费的配套视频可观看 🍅 点击文末小卡片,免费获取软件测试全套资料,资料在手,涨薪更快 一、什么是白盒测试 白盒测试是一种测试策略,这种策略允许我们检查程序的内部结构&a…

Vite: Esbuild的使用与其插件开发

概述 作为 Vite 的双引擎之一,Esbuild 在很多关键的构建阶段(如 依赖预编译 、 TS 语法转译 、 代码压缩 ) 让 Vite 获得了相当优异的性能,是 Vite 高性能的得力助手无论是在 Vite 的配置项还是源码实现中,都包含了不少 Esbuild 本身的基本概…