【Unity开发字典】序列化基类

文章目录

概要

在 数据传输,数据储存方面, 将数据序列化为字节, 是必不可少的步骤;

本文提供了一个序列化基类, 需要序列化的类可以通过, 继承此基类, 实现基类中的虚函数, 实现便捷的序列化操作, 本文在提供基类外, 还附一个案例

基类代码

下面是预览图片, 代码段会附在后边

需要重写的方法

1.public abstract int GetBytesNum();

2.public abstract byte[] Writing();

3.public abstract int Reading(byte[] bytes,int beginIndex = 0);
方法一 :子类重写, 要返回自己序列化后的长度, 创建接收序列化类的容器时,需要使用这个长度来初始化.
方法2: 子类重写, 用下面的序列化工具方法, 在方法2中, 对自己的成员变量进行序列化操作, 返回的是一个二进制字节数组.
方法3: 接收到相应类的字节数组后, 该方法通过下面的解析工具方法 , 对本类型的字节数组 , 进行解读操作, 返回当前Index(索引)位置, 可以方便后续的读取操作
方法3参数:byte[]bytes , 要解读的字节数组, beginIndex 从哪里开始读,默认为0

序列化读写工具

这里只写了常用的数据类型的工具, 可以按照需求写更多, 这里不一样的是,
自定义类的写入 , 自定义类的解读

思路也很简单, 直接调用自定义类里实现的写入和解读, 就可以实现.

写入参数解析:
参数1: byte[]bytes, 传入一个字节数组, 将序列化后的字节, 写入该字节数组;
参数2: 需要序列化的不同类型的信息, 会在方法里进行相应序列化;
参数3: ref int index 当前索引 位置,用于记录当前位于字节数组的哪个位置,用于多次记录时, 准确拼接信息到字节数组末尾;

csharp 复制代码
using System;
using System.Collections;
using System.Collections.Generic;
using System.Text;


public abstract class BaseData {
    /// <summary>
    /// 子类重写, 获取字节数组容器大小
    /// </summary>
    /// <returns></returns>
    public abstract int GetBytesNum();
    /// <summary>
    /// 子类重写, 把成员变量序列为对应字节数组
    /// </summary>
    /// <returns></returns>
    public abstract byte[] Writing();
    /// <summary>
    /// 把2进制字节数组,解析到成员变量中
    /// </summary>
    /// <param name="bytes">字节数组</param>
    /// <param name="beginIndex">开始位置,默认是0</param>
    /// <returns></returns>
    public abstract int Reading(byte[] bytes,int beginIndex = 0);


    protected void WriteInt(byte[] bytes, int value, ref int index) {
        BitConverter.GetBytes(value).CopyTo(bytes, index);
        index += sizeof(int);
    }
    protected void WriteShort(byte[] bytes, short value, ref int index) {
        BitConverter.GetBytes(value).CopyTo(bytes, index);
        index += sizeof(short);
    }
    protected void WriteFloat(byte[] bytes, float value, ref int index) {
        BitConverter.GetBytes(value).CopyTo(bytes, index);
        index += sizeof(float);
    }
    protected void WriteBool(byte[] bytes, bool value, ref int index) {
        BitConverter.GetBytes(value).CopyTo(bytes, index);
        index += sizeof(bool);
    }
    protected void WriteString(byte[] bytes, string value, ref int index) {
        byte[] strbyte = Encoding.UTF8.GetBytes(value);
        BitConverter.GetBytes(strbyte.Length).CopyTo(bytes, index);
        index += sizeof(int);
        strbyte.CopyTo(bytes, index);
        index += strbyte.Length;
    }

    /// <summary>
    /// 自定义类的写入
    /// </summary>
    /// <param name="bytes">要写入的字节数组</param>
    /// <param name="data">此类已经继承BaseData 填写这个类进来</param>
    /// <param name="index">参数</param>
    protected void WriteData(byte[] bytes, BaseData data, ref int index) {
        data.Writing().CopyTo(bytes, index);
        index += data.GetBytesNum();
    }

    protected int ReadInt(byte[]bytes, ref int index) {
        int value = BitConverter.ToInt32(bytes,index);
        index += sizeof(int);
        return value;
    }
    protected short ReadShort(byte[] bytes, ref int index) {
        short value = BitConverter.ToInt16(bytes,index);
        index += sizeof(short);
        return value;
    }
    protected float ReadFloat(byte[] bytes, ref int index) {
        float value = BitConverter.ToSingle(bytes, index);
        index += sizeof(float);
        return value;
    }
    protected bool ReadBool(byte[] bytes, ref int index) {
        bool value = BitConverter.ToBoolean(bytes, index);
        index += sizeof(bool);
        return value;
    }
    protected string ReadString(byte[] bytes, ref int index) {
        int strCount = BitConverter.ToInt32(bytes,index);
        index += 4;
        string str = Encoding.UTF8.GetString(bytes, index, strCount);
        index += strCount;
        return str;
    }
    protected T ReadData<T>(byte[] bytes, ref int index) where T : BaseData , new() {
        T data = new T();
        index += data.Reading(bytes,index);
        return data;
    }


}

案例Player

PlayerData 就是继承BaseData 需要序列化的案例

需要的方法

1.public abstract int GetBytesNum();

2.public abstract byte[] Writing();

3.public abstract int Reading(byte[] bytes,int beginIndex = 0);

1.返回字节长度,

4+4+4+Str(序列化)

atk + lev + str长度(int) + 序列化后的str

2.写入, 创建一个 字节长度大小的数组, 将所有内容写入其中

3.解读 , 返回当前index变化, 连续解读时, 需要用, 给自己成员变量赋值.

csharp 复制代码
using System.Collections;
using System.Collections.Generic;
using System.Text;


public class PlayerData : BaseData
{
    public string name;
    public int atk;
    public int lev;
    public override int GetBytesNum()
    {
        
        return 4+4+4+Encoding.UTF8.GetBytes(name).Length;
    }
    public override int Reading(byte[] bytes, int beginIndex = 0)
    {
        int index = beginIndex;
        name = ReadString(bytes,ref index);
        atk = ReadInt(bytes,ref index);
        lev = ReadInt(bytes,ref index);
        return index - beginIndex;
    }
    
    public override byte[] Writing()
    {
        int index = 0;
        byte[] bytes = new byte[GetBytesNum()];
        WriteString(bytes, name, ref index);
        WriteInt(bytes,atk,ref index);
        WriteInt(bytes,lev,ref index);
        return bytes;
    }
}

在外部调用举例

csharp 复制代码
                PlayerData data= new PlayerData();
                data.Reading(receiveBytes , 0);
                print(data.name);
                print(data.atk);
                print(data.lev);

结语

现在就可以直接复制, 让你的类序列化为二进制了, 接下来我还有几篇文章, 是关于网络开发中的信息传输, 这个是第一篇

相关推荐
雪豹阿伟19 小时前
10.C# —— 数组Array
c#·上位机
csdn_aspnet20 小时前
C# 算法 LeetCode 编号 70 - 爬楼梯
算法·leetcode·c#
魔法阵维护师20 小时前
从零开发游戏需要学习的c#模块,第二十五章(摄像机 —— 让世界比屏幕大)
学习·游戏·c#
周杰伦fans21 小时前
不支持目标框架: C#项目面向不再受支持的.NET Framework4.6.2
开发语言·c#·.net
richard_yuu1 天前
C#零基础通关第六篇:吃透静态、常量与只读,分清静态与实例的本质差异
开发语言·c#
2501_930707781 天前
使用C#代码在 PowerPoint 中组合或取消组合形状
开发语言·c#
玄米乌龙茶1231 天前
LLM成长笔记(十三):系统设计与项目实战
笔记·unity·游戏引擎
baivfhpwxf20232 天前
c# 中对像之间频繁的转换会慢吗?
开发语言·c#