【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);

结语

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

相关推荐
mudtools36 分钟前
在.NET现有系统中快速集成飞书任务分配能力
后端·c#·.net
xiaoye-duck36 分钟前
《Linux 网络编程·加餐》详解 listen 的 backlog 与 TCP 全连接队列
linux·tcp
工具派4 小时前
Word文档太大怎么拆分?段落结构与两种拆法的边界实测
开发语言·c#·word
潜龙95274 小时前
需求文档一键变测试用例:手工用例智能生成平台
开发语言·c#
Lost of 程序猿4 小时前
命令模式实战:把“下单后的动作“打包成可执行的任务
后端·设计模式·c#·asp.net·命令模式
淡海水4 小时前
16-01-C#数据结构源码-附录A-术语表
unity·c#·游戏引擎·il2cpp
小羊没烦恼!4 小时前
【译】利用Asp.net MVC处理文件的上传下载
开发语言·缓存·c#·word·powerpoint·.net
波力海苔夹心脆6755 小时前
C# 海康威视摄像头二次开发入门:HCNetSDK 登录、实时预览、云台控制、录像与抓图(WinForms 实战)
开发语言·windows·经验分享·tcp/ip·c#
淡海水5 小时前
16-03-C#数据结构源码-附录C-参考资源
unity·c#·游戏引擎·il2cpp
天神哥哥啊6 小时前
unity联调注意事项-安卓
android·unity·游戏引擎