2015-05-06 2 views
0

В настоящее время я пишу объектно-ориентированную игру с мультиплеер. Игрока наследует от объекта, и когда я шлю текущие игрок свойство черезC# Lidgren Library - Отправить playerdata

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

где р мой объект игрока, мои клиенты получают только те свойства, которые объявлены в классе игроков, а не от класса объекта. Поэтому мои клиенты не могут обновить позиции игроков и т. Д.

Любые советы?

редактировать:

Он признает, наследуемые предметы, но он не посылает их должным образом. Я думаю, мне, возможно, придется использовать некоторые Bindingflags, поскольку есть опция для него, и должно быть возможно отправить объекты, которые также выделены игроку. Я использую класс Vector2 для указания позиции и скорости моего плеера, но мой клиент либо не может получить класс Vector2, либо сервер не может его отправить. Если я использую целые числа, строки, булевы или что-то, что он работает, но не с пользовательскими классами.

+0

Lidgren по-прежнему довольно низкоуровневая сетевая библиотека.Это не то, что вы просто подключаете к своей игре, и это делает вашу игру многопользовательской (в отличие, скажем, от сети Unity 3D). Определите свои собственные сообщения. Будьте как можно более конкретными, никогда не отправляйте то, что вам не нужно отправлять. Сеть очень сложная, и, хотя Лидгрен спасает вас от многих из этих проблем, это не поможет вам в этом много сделать с многопользовательской игрой. Игры в реальном времени, в частности, очень сложно сделать правильно, особенно если они основаны на твитах. Делайте работу с примитивами - отправляйте эти векторы в виде двух 'float' и т. Д. – Luaan

+0

Перед тем, как я увидел ваш комментарий, я подумал точно так же. Я напишу свой собственный писатель сейчас, спасибо за ответ. – besplash

+0

Это действительно сводится к производительности, в основном. Игровые сообщения обычно не являются самоописательными (в отличие, скажем, с SOF-сообщениями WCF), потому что это тратит пространство и латентность. Если вы хотите что-то помочь вам в построении протоколов сообщений, «protobuf» очень полезно - он позволяет использовать конструкции «более высокого уровня», такие как списки, необязательные параметры, строки и т. Д. У него есть некоторые накладные расходы (естественно), но isn «Трудно использовать. Вы можете сериализовать структуру protobuf в массив байтов и отправить ее напрямую с помощью Lidgren. Но вы по-прежнему отправляете сообщения типа «обновление позиции игрока 1 (1, 1)». – Luaan

ответ

1

Это должно (не пробовал это сам) возможно, так как вы можете сериализовать что-либо в байтах, а не прямо из коробки. Существует 3 основных условия:

  • Объекты, которые необходимо отправить, должны быть точно такими же на клиенте и на сервере.
  • Необходимо отправить тип данных вместе с данными в ожидаемом положении.
  • И, скорее всего, необходимо отправить количество байтов, отправленных с NetIncomingMessage, не было до конца.

Один из способов отправки данных типа информации, чтобы отправить перечисление в качестве первого байта

enum PacketTypes 
{ 
    LOGIN, 
    MOVEMENT, 
    SHOOTING, 
} 

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

NetOutgoingMessage.Write может принять байт или массив байтов. Таким образом, вы можете использовать любой метод для сериализации вашего объекта в байтах. Прежде чем писать это как выходное сообщение, сначала определите количество байтов и напишите это после информации о пакете. Затем напишите данные.

На приемной стороне вам необходимо определить, какие данные вы получили и как правильно их обрабатывать. if (inc.ReadByte() == (byte)PacketTypes.Login), теперь мы знаем, как обращаться с этим пользовательским пакетом. Теперь зачитаем целое число, указывающее, сколько байтов данных, зачитывают эту сумму и десериализуют ее.

Существует множество источников, которые объясняют сериализацию и десериализацию данных, поэтому я не буду углубляться в суть здесь. А так как вы можете отправлять и получать байты с Lidgren, это действительно должно просто работать. Однако вы всегда должны отправлять как можно меньше данных, и на практике достаточно нескольких примитивов. Например, имя игрока не нужно посылать каждый раз, когда вы хотите занятие. Возможности этого игрока, вероятно, еще менее интересны. Вам нужно разбить его на куски, если игрок перемещает отправку 2 поплавков. Если игрок получает удар, отправьте int. Для использования способности вам часто требуется только целое число в качестве идентификатора.

+0

В настоящее время я также очень уверен, что ваш подход работает, и если бы мне пришлось отправить целый объект, который мог бы быть лучшим решением для него. Однако я не думаю, что отправка целого объекта в этом случае является оптимальной. В любом случае я буду принимать это как самое полезное решение, так как оно должно решить мою упомянутую проблему. Надеюсь, это поможет кому-то! – besplash