当前位置: 首页 > news >正文

Unity Netcode自定义数据传输——结构体及其序列化

在 Unity Netcode 中,要实现自定义数据的网络传输,确实需要两个关键部分:

✅ 两个必需组件:

  1. 数据结构定义

    public struct PlayerState : INetworkSerializable
    {public int id;          // 字段1:玩家IDpublic bool isReady;    // 字段2:准备状态// ...其他字段
    }
    
    • 作用:定义要传输的数据内容
    • 本质:声明"要传输什么"
  2. 序列化方法实现

    public void NetworkSerialize<T>(BufferSerializer<T> serializer)
    {serializer.SerializeValue(ref id);       // 处理字段1serializer.SerializeValue(ref isReady);  // 处理字段2// ...处理其他字段
    }
    
    • 作用:控制数据如何打包/解包
    • 本质:定义"如何传输"

类比解释(快递包裹)

网络传输快递包裹类比
数据结构要寄送的物品
NetworkSerialize 方法打包/拆包的操作说明书
网络管道快递运输通道
接收方收件人
  1. 发送方

    • 按照说明书(NetworkSerialize)打包物品(数据)
    • 通过快递(网络)寄出
  2. 接收方

    • 收到包裹
    • 按照相同的说明书NetworkSerialize)拆包
    • 获得完全相同的物品(数据)

为什么必须两者结合?

  1. 没有数据结构 → 不知道传输什么内容

    // 无效:不知道传输什么
    public void NetworkSerialize<T>(...) {// 没有字段可序列化
    }
    
  2. 没有序列化方法 → 不知道如何传输

    // 编译错误:未实现接口
    public struct PlayerState : INetworkSerializable {public int id;// 缺少NetworkSerialize方法
    }
    

完整工作流程

发送端 网络 接收端 准备数据 1. 创建PlayerState实例 2. 填充数据(id=101, isReady=true) 序列化(打包) 3. 调用NetworkSerialize - 写入id(101) - 写入isReady(true) 4. 发送二进制数据 5. 传输数据 反序列化(解包) 6. 创建空的PlayerState 7. 调用NetworkSerialize - 读取id → 101 - 读取isReady → true 8. 获得完整数据 发送端 网络 接收端

特殊注意事项

  1. 字段顺序必须严格一致
    发送端和接收端的序列化顺序必须完全相同:

    // ✅ 正确顺序
    serializer.SerializeValue(ref id);
    serializer.SerializeValue(ref isReady);// ❌ 危险!顺序不一致会导致数据错乱
    serializer.SerializeValue(ref isReady);
    serializer.SerializeValue(ref id);
    
  2. 新增字段的版本处理
    如果后续增加字段,需要处理兼容性:

    public string name; // 新增字段public void NetworkSerialize<T>(...)
    {serializer.SerializeValue(ref id);serializer.SerializeValue(ref isReady);// V2新增字段if (serializer.IsReader) {// 处理旧版本数据缺失的情况name = "默认名称";}serializer.SerializeValue(ref name);
    }
    
  3. 值类型 vs 引用类型

    • 结构体(值类型):直接使用 ✅
    • 类(引用类型):需要特殊处理 ❗
      public class Weapon // 引用类型
      {public int damage;
      }// 在序列化方法中需要:
      if (serializer.IsWriter) {serializer.SerializeValue(ref weapon.damage);
      } else {weapon = new Weapon();serializer.SerializeValue(ref weapon.damage);
      }
      

最终总结

组件必须存在作用
数据结构定义声明要传输的数据内容
NetworkSerialize 方法定义数据如何打包/解包
: INetworkSerializable 接口标记该类型支持网络序列化

三者缺一不可,共同实现 Unity Netcode 的自定义数据网络传输能力。

http://www.lqws.cn/news/534781.html

相关文章:

  • .NET测试工具Parasoft dotTEST内置安全标准,编码合规更高效
  • 基于STM32的智能书房系统的设计
  • SpringBoot定时任务 - Timer实现方式
  • 算法打卡 day4
  • 大数据赋能智慧城市:从数据洪流到科学规划的“智慧之匙”
  • Leetcode百题斩-DP
  • 全面学习 OpenAI API:从 Python 教程到 API Key 使用详解,快速上手调用和部署
  • 微服务分布式事务解决方案
  • Beam2.61.0版本消费kafka重复问题排查
  • Git 使用规范与命令使用场景详解
  • 【Excel数据分析】花垣县事业单位出成绩了,用Excel自带的M语言做一个数据分析
  • 45. 跳跃游戏 II
  • uniapp 和原生插件交互
  • Sentinel 授权规则详解与自定义异常处理
  • Tailwind CSS 尺寸控制
  • c++多线程编程
  • 《聊一聊ZXDoc》之汽车标定、台架标定、三高标定
  • 基于定制开发开源AI智能名片S2B2C商城小程序源码的H5游戏开发模式创新研究
  • 从零开始的云计算生活——第二十四天,重起航帆,初见MySQL数据库
  • 智能体决策框架对决:ReAct极速响应 vs Plan-and-Execute稳控全局
  • 【全志V821_FoxPi】3-2 Linux 5.4 SPI + XPT2046触摸(ADS7846) + tslib
  • SQL SERVER存储过程
  • 分享一些实用的PHP函数(对比js/ts实现)
  • VIVADO设定寄存器/存储器的初始值
  • 深入解析与修复 Linux 中的种种依赖项错误:Dependencies packages error solution
  • 【UniApp 日期选择器实现与样式优化实践】
  • 03.图生图基础工作流|提示词自动化|存储节点预设|提示词风格化
  • 以太网基础与 VLAN 配置实验
  • Vue3中的watch详解:掌握响应式侦听的艺术
  • 本地部署开源时间跟踪工具 Kimai 并实现外部访问( Windows 版本)