当前位置: 首页 > 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 的自定义数据网络传输能力。

相关文章:

  • Docker数据管理——AI教你学Docker
  • Django入门教程:从零构建Web应用
  • Android-Layout Inspector使用手册
  • 【STM32】外部中断
  • SQL Server 如何实现高可用和读写分离技术架构
  • 信创领域下大数据技术的落地应用场景探析
  • Spring Boot高并发 锁的使用方法
  • 【1-认识three.js与开发环境搭建】
  • LeetCode Hot100(回溯)
  • 2025 Java开发生态全景图:云原生、AI与性能优化的技术融合
  • 通达信 股道主力资金 幅图分析系统
  • 机器学习17-发展历史补充
  • 一分钟了解Transformer
  • spring-ai 1.0.0 (1)模型调用能力
  • Vue样式绑定与条件渲染详
  • MS91051模拟前端可Pin to Pin兼容LMP91051
  • 数据结构进阶 - 第三章 栈与队列
  • 专题:2025中国游戏科技发展研究报告|附130+份报告PDF、原数据表汇总下载
  • flutter结合ai工具(其他语言通用)
  • SpringBoot 中使用 @Async 实现异步调用​