C# Lidgren 库 - 发送播放器数据
C# Lidgren Library - Send playerdata
我目前正在编写一款面向对象的多人游戏。
玩家继承自实体,当我通过
发送我当前的玩家属性时
NetOutgoingMessage outmsg = Server.CreateMessage();
[...]
outmsg.WriteAllProperties(p);
其中 p 是我的玩家对象,我的客户只接收在我的玩家 class 中声明的属性,而不是来自实体 class 的属性。因此我的客户无法更新玩家位置等
有什么建议吗?
编辑:
它识别继承的对象,但没有正确发送它们。我想我可能需要使用一些 Bindingflags 因为它有一个选项并且应该可以发送分配给玩家的对象。我正在使用 Vector2 class 来指定我的播放器的位置和速度,但我的客户端无法接收 Vector2 class 或者服务器无法发送它。如果我使用整数、字符串、布尔值或任何它有效的东西,但不适用于自定义 classes.
我刚刚(终于)读到,Lidgren 无法发送或读取自定义对象。
https://groups.google.com/forum/#!topic/lidgren-network-gen3/sdj6LFMdKAY
这应该(我自己还没有尝试过)是可能的,因为您可以将任何内容序列化为字节,但不是直接开箱即用。有3个主要条件:
- 需要发送的对象在客户端和服务器上应该完全相同。
- 您需要将数据类型与预期位置的数据一起发送。
- 并且很可能需要发送字节数,因为
NetIncomingMessage
没有读取到结束。
发送数据类型信息的一种方法是将枚举作为第一个字节发送
enum PacketTypes
{
LOGIN,
MOVEMENT,
SHOOTING,
}
out.Write((byte)PacketTypes.Login);
NetOutgoingMessage.Write
可以采用字节或字节数组。所以你可以使用任何方法将你的对象序列化为字节。在将其写为输出消息之前,首先确定字节数并将其写在数据包信息之后。然后写入数据。
在接收端,您需要确定接收到的数据类型并妥善处理。 if (inc.ReadByte() == (byte)PacketTypes.Login)
,现在我们知道如何处理这个自定义包了。现在读出指定数据有多少字节的整数,读出该数量并反序列化它。
有很多资源可以解释序列化和反序列化数据,因此我不会在这里深入探讨。由于您可以使用 Lidgren
发送和接收字节,这确实 应该 可以正常工作。但是,您应该始终发送尽可能少的数据,实际上几个原语通常就足够了。例如,玩家的名字不需要每次你想要一个位置时都发送。该玩家的能力可能更不有趣。你需要把它分解成碎片,如果玩家移动发送 2 个花车。如果玩家被击中,发送一个 int。对于正在使用的能力,您通常只需要一个整数作为 ID。
我目前正在编写一款面向对象的多人游戏。 玩家继承自实体,当我通过
发送我当前的玩家属性时NetOutgoingMessage outmsg = Server.CreateMessage();
[...]
outmsg.WriteAllProperties(p);
其中 p 是我的玩家对象,我的客户只接收在我的玩家 class 中声明的属性,而不是来自实体 class 的属性。因此我的客户无法更新玩家位置等
有什么建议吗?
编辑:
它识别继承的对象,但没有正确发送它们。我想我可能需要使用一些 Bindingflags 因为它有一个选项并且应该可以发送分配给玩家的对象。我正在使用 Vector2 class 来指定我的播放器的位置和速度,但我的客户端无法接收 Vector2 class 或者服务器无法发送它。如果我使用整数、字符串、布尔值或任何它有效的东西,但不适用于自定义 classes.
我刚刚(终于)读到,Lidgren 无法发送或读取自定义对象。
https://groups.google.com/forum/#!topic/lidgren-network-gen3/sdj6LFMdKAY
这应该(我自己还没有尝试过)是可能的,因为您可以将任何内容序列化为字节,但不是直接开箱即用。有3个主要条件:
- 需要发送的对象在客户端和服务器上应该完全相同。
- 您需要将数据类型与预期位置的数据一起发送。
- 并且很可能需要发送字节数,因为
NetIncomingMessage
没有读取到结束。
发送数据类型信息的一种方法是将枚举作为第一个字节发送
enum PacketTypes
{
LOGIN,
MOVEMENT,
SHOOTING,
}
out.Write((byte)PacketTypes.Login);
NetOutgoingMessage.Write
可以采用字节或字节数组。所以你可以使用任何方法将你的对象序列化为字节。在将其写为输出消息之前,首先确定字节数并将其写在数据包信息之后。然后写入数据。
在接收端,您需要确定接收到的数据类型并妥善处理。 if (inc.ReadByte() == (byte)PacketTypes.Login)
,现在我们知道如何处理这个自定义包了。现在读出指定数据有多少字节的整数,读出该数量并反序列化它。
有很多资源可以解释序列化和反序列化数据,因此我不会在这里深入探讨。由于您可以使用 Lidgren
发送和接收字节,这确实 应该 可以正常工作。但是,您应该始终发送尽可能少的数据,实际上几个原语通常就足够了。例如,玩家的名字不需要每次你想要一个位置时都发送。该玩家的能力可能更不有趣。你需要把它分解成碎片,如果玩家移动发送 2 个花车。如果玩家被击中,发送一个 int。对于正在使用的能力,您通常只需要一个整数作为 ID。