zoukankan      html  css  js  c++  java
  • Unity Mirror 自定义序列化器传输数据

    Mirror支持许多内建类型的传输,具体可参考Mirror的NetworkWriter类的定义。

    而一些自定义的类型,比如下面这个:

    using Mirror;
    using UnityEngine;
    
    public class CustomDataTypes : NetworkBehaviour
    {
        public class Item
        {
            public string name;
        }
    
        public class Armour : Item
        {
            public int protection;
            public int weight;
        }
    
        public class Potion : Item
        {
            public int health;
        }
    
        public override void OnStartAuthority()
        {
            base.OnStartAuthority();
    
            Potion potion = new Potion();
            potion.name = "Health Potion";
            potion.health = 5;
    
            CmdSendItem(potion);
        }
    
        [Command]
        private void CmdSendItem(Item item)
        {
            if(item is Item)
                Debug.Log("Item name is " + item.name);
    
            if (item is Potion potion)
                Debug.Log("Potion gives " + potion.health + " health.");
        }
    }
    

      

    其中存在继承关系,如果尝试直接传输,会发现CmdSendItem的第二条log没有输出:

    下面提供一种自定义序列化器:

    using Mirror;
    using System;
    using static CustomDataTypes;
    
    public static class ItemSerializer
    {
        private const byte ITEM_ID = 0;
        private const byte POTION_ID = 1;
        private const byte ARMOUR_ID = 2;
    
        public static void WriteItem(this NetworkWriter writer, Item item)
        {
            if(item is Potion potion)
            {
                writer.WriteByte(POTION_ID);
                writer.WriteString(potion.name);
                writer.WritePackedInt32(potion.health);
            }
            else if(item is Armour armour)
            {
                writer.WriteByte(ARMOUR_ID);
                writer.WriteString(armour.name);
                writer.WritePackedInt32(armour.protection);
                writer.WritePackedInt32(armour.weight);
            }
            else
            {
                writer.WriteByte(ITEM_ID);
                writer.WriteString(item.name);
            }
        }
    
        public static Item ReadItem(this NetworkReader reader)
        {
            byte id = reader.ReadByte();
    
            switch (id)
            {
                case POTION_ID:
                    return new Potion
                    {
                        name = reader.ReadString(),
                        health = reader.ReadPackedInt32()
                    };
                case ARMOUR_ID:
                    return new Armour
                    {
                        name = reader.ReadString(),
                        protection = reader.ReadPackedInt32(),
                        weight = reader.ReadPackedInt32()
                    };
                case ITEM_ID:
                    return new Item
                    {
                        name = reader.ReadString()
                    };
                default:
                    throw new Exception($"Unhandled item type for {id}.");
            }
        }
    }
    

      

    再次运行:

    可以看到成功打印出Potion的health数据

  • 相关阅读:
    Vue.js中使用iView日期选择器并设置开始时间结束时间校验
    侠客行
    myJRebel 已不可用
    开发.NET Core NuGet包并实现CI/CD
    独立部署GeoWebCache
    GeoServer中GeoWebCache(GWC)的使用
    使用VS Code编写Markdown文件
    GitHub团队协作流程
    打包发布到NPM并通过CDN访问
    使用VS Code编写Markdown文件
  • 原文地址:https://www.cnblogs.com/yl-xy/p/13389830.html
Copyright © 2011-2022 走看看