Вместе с моим другом мы начали разработку многопользовательской игры с использованием API транспортного уровня (UNET LLAPI?), доступного с игровым движком Unity.
Из-за необходимости иметь до сотни одновременных пользователей в поле зрения других игроков, мне было интересно, как наиболее эффективно отправлять сообщения о позиции игрока, его вращении и т. д.
До сих пор, адаптируя учебник (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)