Unity如何保存玩家的数据(Unity的二进制序列化)

news2024/11/18 13:44:38

文章目录

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

什么是二进制序列化

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 update
    void 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.coloradmin.cn/o/1857008.html

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

相关文章

傅佩荣讲座视频全集百度网盘,傅佩荣讲座视频大全百度云

在当今信息爆炸的时代,获取知识的途径日益多元化,其中,通过网络观看各类教学视频已成为众多学习者的首选。傅佩荣教授的视频课程深受广大学者的喜爱。然而,对于许多初学者来说,如何下载傅佩荣的视频却是一个难题。本文…

Flutter 面试八股之深入理解 Dart 异步实现机制

为什么写这一篇内容?因为在此之前关于 《面试题里有意思的异步问题》 的文章收到一些「问题」,但是解释这些「问题」并不是“三言两语”就可以说清,所以干脆做一篇完整解析,相信本篇可以帮助你从头到尾理清 Flutter 里 Dart 的完整…

创新、引领、发展——SAMPE中国2024年会在京盛大开幕

绿树阴浓夏日长,在这个色彩缤纷的季节,SAMPE中国2024年会暨第十九届国际先进复合材料制品原材料、工装及工程应用展览会在中国国际展览中心(北京朝阳馆)隆重开幕。新老朋友共聚一堂,把酒话桑麻。 为期4天的国际学术会…

公共筛选组件(二次封装antd)支持代码提示

如果项目是基于antd组件库为基础搭建,可使用此公共筛选组件 使用到的库 npm i antd npm i lodash-es npm i types/lodash-es -D/components/CommonSearch index.tsx import React from react; import { Button, Card, Form } from antd; import styles from ./…

LED显示屏的换帧频率与刷新频率:技术细节与市场发展

在当今数字化时代,LED显示屏已成为信息传递和广告宣传的重要工具。然而,对于普通消费者来说,LED显示屏背后的技术细节可能仍然是一个谜。今天,我们将深入探讨LED显示屏中的两个关键概念:换帧频率和刷新频率&#xff0c…

ARM功耗管理软件之WFIWFE

安全之安全(security)博客目录导读 思考:功耗管理软件栈及示例?WFI&WFE?时钟&电源树?DVFS&AVS? ARM功耗管理精讲与实战汇总参见:Arm功耗管理精讲与实战

PS系统教程26

PS与BR的关系 如何把图片以图层的方式导入画板里面 选中三张图片/多张选择工具-PS-将文件载入PS图层意味着这三张图片以图层的方式嵌入PS中 拼接长图 裁剪图片 保存裁剪后的图片拼接图片选中要拼接的图片选择工具-PS-Photomerge(拼合图像) 图像处理器 大白话&…

APM教程-SkyWalking安装和配置

SkyWalking简介 APM (Application Performance Management) 即应用性能管理,属于IT运维管理(ITOM)范畴。主要是针对企业 关键业务的IT应用性能和用户体验的监测、优化,提高企业IT应用的可靠性和质量,保证用户得到良好的服务&#…

IDEA中 pom.xml 设置自动提示

IDEA中 pom.xml 自动提示 IDEA中 pom.xml 自动提示设置如下: file–>Settings–>Build,Execution…–>Build Tools–>Maven–>Repositories 会看到类似表格的画面,内容是你的maven地址,选中后,右边有个Update的按…

轻量级在线服装3D定制引擎Myway简介

我写的面向web元宇宙轻量级系列引擎中的另外一个,在线3D定制引擎Myway 3D。 用于在线商品定制,比如个性化服装的定制、日常用品(如杯子)、家装(被套)等物品的在线定制。 特性列表: 可更换衣服…

会话会话会话

目录 1.会话 1.1 为什么需要会话控制 1.2 域对象的范围 1.2.1 应用域的范围 1.2.2 请求域的范围 1.2.3 会话域的范围 1.3 Cookie技术 1.3.1 Cookie的概念 1.3.2 Cookie的作用 1.3.3 Cookie的应用场景 1.3.4 Cookie的入门案例 ① 目标 ② Cookie相关的API ③ Serv…

Python自动化(8)——pyqt5界面

Python自动化(8)——pyqt5界面 注意:pyqt5的界面使用时必须有app QApplication(sys.argv)这行代码,否则会出现错误并且无法显示窗口:QWidget: Must construct a QApplication before a QWidget 一些基础的控件 QMainWindow QMainWindow是…

ESP32 esp-idf esp-adf环境安装及.a库创建与编译

简介 ESP32 功能丰富的 Wi-Fi & 蓝牙 MCU, 适用于多样的物联网应用。使用freertos操作系统。 ESP-IDF 官方物联网开发框架。 ESP-ADF 官方音频开发框架。 文档参照 https://espressif-docs.readthedocs-hosted.com/projects/esp-adf/zh-cn/latest/get-started/index.…

(1995-2022年) 全国各省份-技术交易活跃度

技术交易活跃度是一个关键指标,用于衡量技术市场的交易频繁程度和活跃性。它不仅显示了市场参与者对技术交易的参与热情,而且交易的频率也体现了市场的活力。这一指标对于不同的利益相关者具有不同的意义: 对投资者而言,技术交易…

尚硅谷k8s

p1-6 阿里云服务器开通流程 阿里云服务器购买等各种操作,省略 p7 私有网络vpc实战 VPC(Virtual Private Cloud)网络,是一种基于云计算的网络服务,旨在为用户提供在公有云上自定义的、逻辑隔离的网络空间。 设置vpc可以使网络之…

让生产管理变简单

随着业务的发展,工厂每天要处理很多订单,还要统筹安排各部门工作以及协调上下游加工企业,生产管理问题也随之而来。 1.销售订单评审困难、无法及时抓取到历史数据做参考。由于数据的不及时性、不准确性无法为正常的生产和采购提供数据支撑。同…

Linux关闭swap分区操作[适用于CDH报警等]

1.查看swap分区挂载路径(没卵用) swapon -s 2.设置配置文件的swap配置 echo “vm.swappiness 0” > /etc/sysctl.conf 3.设置内存中的swap状态。有时候配置文件为0,但集群或服务仍然使用了swap分区,可能原因就是内存没有同步配置 echo “0” > …

X-AnyLabeling使用教程

1.AI 模型自动分割标注使用教程 2.AI 模型自动目标检测标注使用教程

HTML(23)——垂直对齐方式

垂直对齐方式 属性名:vertical-align 属性值效果baseline基线对齐(默认)top顶部对齐middle居中对齐bottom底部对齐 默认情况下浏览器对行内块,行内标签都按文字处理,默认基线对齐 导致图片看起来会偏上,文字偏下。 示例&#…

React+TS前台项目实战(十七)-- 全局常用组件Dropdown封装

文章目录 前言Dropdown组件1. 功能分析2. 代码详细注释3. 使用方式4. 效果展示 总结 前言 今天这篇主要讲全局Dropdown组件封装,可根据UI设计师要求自定义修改。 Dropdown组件 1. 功能分析 (1)通过position属性,可以控制下拉选项的位置 &am…