Mirror支持许多内建类型的传输,具体可参考Mirror的NetworkWriter类的定义。这里提供一个自定义序列化传输数据的方法。
而一些自定义的类型,比如下面这个:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42
| 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没有输出:
![]()
下面提供一种自定义序列化器:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61
| 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数据