Custom Data Types(自定义数据类型)
本篇介绍一般情况下能通过Network传输的变量。
一般结构体能通过Network传递,
一般类能传递,但是有继承的类,不行
需要custom serialize。
举例:
(基础操作已省略,具体操作同→这里)
代码:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Mirror;public class CustomDataTypes : NetworkBehaviour
{
#region Will serialize
public struct A
{
public byte ID;
public Vector3 Position;
}public class B
{
public string Name;
//Won't serialize if ItemStats is null
public C stats;
}
/* Will serialize because it uses built-in types.
* Any type which isn't built in would need to have a
* serializer made.*/
public class C
{
public int count;
}
#endregion#region Demo Classes
public class Item
{
public string Name;
}
/*The Next 2 classes will not serialize over the Network without
* making a custom serializer*/
public class Armour : Item
{
public int Protection;
public int Weight;
}public class Potion : Item
{
public int Health;
}
#endregionpublic override void OnStartAuthority()
{
base.OnStartAuthority();Potion pot = new Potion();
pot.Name = "Health Potion";
pot.Health = 5;
CmdSendItem(pot);
}[Command]
private void CmdSendItem(Item item)
{
if (item is Item)
Debug.Log("My Name is"+item.Name+".");
if(item is Potion potion)
Debug.Log("My potion gives"+potion.Health+" health.");
}
}
结果:
如图所示,
Debug.Log("My potion gives"+potion.Health+" health.");
这一句明显没有执行。
这就是为什么要需要custom serialize。
那么该怎么做呢?
这里直接写一个Script就行了。
注意,并不需要挂到任何物体上。
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的内容正确地输出了。
如果你想传递其他子类,那就必须继续补全ItemSerializer这个静态类。
Today's comments have reached the limit. If you want to comment, please wait until tomorrow (UTC-Time).
There is 18h41m52s left until you can comment.