UNET Transport Level API Эффективная обработка сообщений и типы - PullRequest
0 голосов
/ 07 июня 2018

Вместе с моим другом мы начали разработку многопользовательской игры с использованием API транспортного уровня (UNET LLAPI?), Доступного с движком Unity Game.

Из-за необходимости иметь до стаПараллельные пользователи в поле зрения других игроков Мне было интересно, что является наиболее эффективным способом отправки сообщений о позиции игрока, ротации и т. д.

Пока, исходя из учебника (1) на Youtube, мы быливозможность настроить систему, в которой обновляются только позиции разных движущихся игроков.Однако даже при одновременном перемещении только 5 игроков обновление позиций на разных клиентах происходит с большой задержкой.

Я полагаю, что это связано с типом строковой переменной, используемой для сообщений с различными данными.Поэтому мой главный вопрос заключается в том, как использовать события данных API транспортного уровня Unity с максимальной эффективностью для каждого сообщения (в этом случае давайте просто скажем для обновлений позиций, где возможно перемещение в любом направлении трехмерного пространства (x, y, z))

Вот код, который мы имеем для серверного скрипта ... Как и в учебном пособии перед вызовом правильной функции, каждая строка сообщения разделяется соответствующими разделителями, разделяющими аргументы, полученные от клиента.Клиент имеет аналогичную систему приема сообщений с другим набором функций.Код, приведенный ниже, конечно, находится в функции «Обновление» серверного скрипта.

NetworkEventType recData = NetworkTransport.Receive(out recHostId, out connectionId, out channelId, recBuffer, bufferSize, out dataSize, out error);
    switch (recData)
    {
        case NetworkEventType.Nothing:
            break;
        case NetworkEventType.ConnectEvent:
            Debug.Log("Player " + connectionId + " has connected");
            OnConnection(connectionId);
            break;
        case NetworkEventType.DataEvent:
            string msg = Encoding.Unicode.GetString(recBuffer, 0, dataSize);
            Debug.Log("Receving from " + connectionId + " : " + msg);
            string[] splitData = msg.Split('|');

            switch (splitData[0])
            {
                case "NAMEIS":
                    OnNameIs(connectionId, splitData[1]);
                    break;

                case "MYPOSITION":
                    OnMyPosition(connectionId, float.Parse(splitData[1]), float.Parse(splitData[2]), float.Parse(splitData[3]));
                    break;

                case "MOVESELECT":
                    OnMoveSelect(connectionId, bool.Parse(splitData[1]), new Vector3(float.Parse(splitData[2]), float.Parse(splitData[3]), float.Parse(splitData[4])));
                    break;
                case "NEWPLAYERSTARTED":
                    OnNewPlayerStarted(connectionId);
                    break;
                case "POSITIONTOANOTHER":
                    OnPositionToAnother(connectionId, float.Parse(splitData[1]), float.Parse(splitData[2]), float.Parse(splitData[3]), int.Parse(splitData[4]));
                    break;
                default:
                    Debug.Log("invalid Message : " + msg);
                    break;
            }
            break;
        case NetworkEventType.DisconnectEvent:
            Debug.Log("Player " + connectionId + " has disconnected");
            OnDisconnection(connectionId);
            break;
        case NetworkEventType.BroadcastEvent:

            break;
    }

Ссылки: 1. https://www.youtube.com/watch?v=qGkkaNkq8co (адаптированный учебник UNET)

1 Ответ

0 голосов
/ 07 июня 2018

NetworkTransport.Receive использует очередь и выскакивает по одному элементу за раз.

Вместо непосредственного выполнения его в обновлении, попробуйте обернуть его через некоторое время, что должно улучшить производительность

int recHostId;
int connectionId;
int channelId;
int dataSize;
byte error;
NetworkEventType recData = NetworkEventType.Nothing;
do {
    recData = NetworkTransport.Receive (out recHostId, out connectionId, out channelId, workingBuffer, workingBuffer.Length, out dataSize, out error);
    if (recData == NetworkEventType.Nothing) {
        break;
    }
    byte[] recBuffer = new byte[dataSize];

    if (dataSize > 0) {
        Buffer.BlockCopy (workingBuffer, 0, recBuffer, 0, dataSize);
    }

    // Switch statement
} while (recData != NetworkEventType.Nothing);

источник

...