1

我目前正在编写一个多人游戏的面向对象游戏。播放器继承自实体,当我通过发送当前播放器属性时

NetOutgoingMessage outmsg = Server.CreateMessage(); [...] outmsg.WriteAllProperties(p);

其中 p 是我的播放器对象,我的客户只接收在我的播放器类中声明的属性,而不是从实体类中声明的属性。因此我的客户无法更新玩家位置等。

有什么建议吗?

编辑:

它识别继承的对象,但不能正确发送它们。我想我可能需要使用一些 Bindingflags,因为它有一个选项,并且应该可以发送分配给玩家的对象。我正在使用 Vector2 类来指定播放器的位置和速度,但我的客户端要么无法接收 Vector2 类,要么服务器无法发送它。如果我使用整数、字符串、布尔值或任何它可以工作的东西,但不适用于自定义类。

4

2 回答 2

2

这应该(我自己没有尝试过)是可能的,因为您可以将任何内容序列化为字节,但不能直接开箱即用。有3个主要条件:

  • 需要发送的对象在客户端和服务器上应该完全相同。
  • 您需要将数据类型与预期位置的数据一起发送。
  • 并且很可能需要发送发送的字节数,因为NetIncomingMessage直到最后都没有读取。

发送数据类型信息的一种方法是将枚举作为第一个字节发送

enum PacketTypes
{
    LOGIN,
    MOVEMENT,
    SHOOTING,
}

out.Write((byte)PacketTypes.Login);

NetOutgoingMessage.Write可以采用字节或字节数组。因此,您可以使用任何方法将对象序列化为字节。在将其作为输出消息写入之前,首先确定字节数并将其写入数据包信息之后。然后写入数据。

在接收端,您需要确定收到的数据类型并正确处理。if (inc.ReadByte() == (byte)PacketTypes.Login),现在我们知道如何处理这个自定义包了。现在读出指定数据字节数的整数,读出该数量并反序列化它。

有很多资源可以解释序列化和反序列化数据,所以我不会在这里深入。而且由于您可以使用它发送和接收字节,Lidgren因此确实应该可以工作。但是,您应该始终发送尽可能少的数据,实际上几个原语通常就足够了。例如,每次您想要一个位置时,都不需要发送玩家的名字。该玩家的能力可能更不有趣。如果玩家移动发送 2 个浮点数,您需要将其分解成碎片。如果玩家被击中,则发送一个 int。对于正在使用的能力,您通常只需要一个整数作为 ID。

于 2016-10-02T07:33:00.967 回答
0

我刚刚(终于)读到,Lidgren 无法发送或读取自定义对象。

https://groups.google.com/forum/#!topic/lidgren-network-gen3/sdj6LFMdKAY

于 2015-05-06T12:59:51.833 回答