Unity——脚本与序列化

这篇具有很好参考价值的文章主要介绍了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 frame
    void 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中。文章来源地址https://www.toymoban.com/news/detail-801300.html

到了这里,关于Unity——脚本与序列化的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Unity基于Google Protobuf序列化和反序列化小案例

    1.协议定义,简单实现传玩家的2D坐标    2.在Unity的Assets目录下创建一个Plugins文件夹(必须这样命名),此文件专门存放扩展文件, 再新建文件夹BaseInfolibrary,将Google.Protobuf.dll拖入  3.新建一个Test.cs脚本  脚本中引入命名空间 代码改进:通用序列化模板(只用来序列化Message)

    2024年02月15日
    浏览(34)
  • unity中,什么是序列化资源?

    好的,以下是序列化资源(Serialized Asset)的详细解释,包括介绍、方法和举例: 在Unity中,序列化资源是指将Unity场景或预制件中的对象及其属性保存到磁盘上的文件中,以便在将来将其还原为原始状态。序列化资源文件可以包括场景文件(.unity)和预制件文件(.prefab),它

    2024年02月10日
    浏览(40)
  • 在Unity中使用Protobuf进行序列化

    目录 1.介绍 1.1 什么是Protobuf 1.2 Protobuf和其他数据序列化方案对比 2.下载Protobuf 2.1 方案一 使用VS的Nuget包管理器进行安装(推荐) 2.1.1安装Protobuff包 2.1.2拷贝.dll文件 2.2 方案二 从Github下载并自己生成.dll 2.2.1 下载Probuff 2.2.2 VS打开解决方案 2.2.3 安装.NET SDK 2.2.4 生成.dll文件 3

    2024年04月12日
    浏览(51)
  • Unity XML3——XML序列化

    ​ 序列化:把对象转化为可传输的字节序列过程称为序列化,就是把想要存储的内容转换为字节序列用于存储或传递 ​ 反序列化:把字节序列还原为对象的过程称为反序列化,就是把存储或收到的字节序列信息解析读取出来使用 1.准备数据结构 2.进行序列化 XmlSerializer:用

    2024年02月15日
    浏览(35)
  • 【工具篇】SerializableDictionary字典序列化Unity面板显示

    目录 一:导入插件 二:创建目标字典类 三:生成数据  四:自定义配置数据 Unity本身对字典这种数据结构没有序列

    2024年02月15日
    浏览(37)
  • unity 通过 二维数组序列化 实现二维数组在编辑器面板查看和配置数据

    实现思路如下: 1、定义一个二维数组数据类 2、奖数据类标记为 Serializable  并实现 unity内置的  ISerializationCallbackReceiver接口,接口提供了序列化和反序列化方法,参见官方文档(文档中给出了字典的序列化方法):Unity - Scripting API: ISerializationCallbackReceiver 3、使用unity序列化

    2024年02月08日
    浏览(44)
  • Unity Image(RawImage) 实现按轴心放大缩小,序列化存储轴心信息,实现编译器窗口保存轴心

    工作时分配给我的要实现的功能,写的时候遇到挺多的坑的,在此记录一下 放大缩小的效果 2.编译器扩展窗口记录 1.打开WSC/保存图片轴心工具,在Image位置挂在需要保存轴心的图像,输出name作为key,并在Scene窗口中直接拖动轴心确定位置(不建议在Inspector中手动输入轴心修改

    2024年02月14日
    浏览(49)
  • C#: Json序列化和反序列化,集合为什么多出来一些元素?

    如下面的例子,很容易看出问题: 如果类本身的无参构造函数, 就添加了一些元素,序列化,再反序列化,会导致元素增加。 如果要避免,必须添加: new JsonSerializerSettings() { ObjectCreationHandling = ObjectCreationHandling.Replace }

    2024年02月10日
    浏览(56)
  • C#使用MongoDB-第二章 序列化

    这里在C#中所使用的连接MongoDB数据库的依赖库为 MongoDB.Driver ,使用前先到Nuget中进行安装。 默认情况下,在我们对MongoDB数据库进行CRUD时,MongoDB.Driver(以后简称驱动库)会自动为我们根据属性、属性类型,将实体类型转换为对应的BSON。 实体类 对应的BSON 1、主键Id 默认情况

    2024年01月22日
    浏览(50)
  • c#示例-json序列化和json树

    由于指针和引用类型的存在,在运行中的程序中,数据不一定是整块的。 可能东一块西一块散落在内存的各个地方。 序列,是指连续且有序的一个整体。序列化就是把数据变为连续有序整体的过程。 经过这样处理后的数据就可以方便的进行传输和储存了。 json是一种文本数

    2024年02月16日
    浏览(80)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包