Важно: UNet — это устаревшее решение, а также новая многопользовательская и сетьсистема Unity, которая обеспечивает многопользовательскую игру. игры через компьютерную сеть. Подробнее См. в Словарь Решение (Netcode для GameObjects) находится в разработке. Дополнительную информацию и дальнейшие действия см. на веб-сайте Unity Netcode for GameObjects. |
Помимо высокоуровневого сетевого API (HLAPI), Unity также предоставляет доступ к низкоуровневому сетевому API, который называется транспортный уровень. . Транспортный уровень позволяет создавать собственные сетевые системы с более специфическими или расширенными требованиями к сети вашей игры.
Транспортный уровень — это тонкий уровеньСлои в Unity можно использовать для выборочного включения или исключения групп игровых объектов из определенных процессов или вычислений. Это включает в себя рендеринг камеры, освещение, физические коллизии или пользовательские вычисления в вашем собственном коде. Подробнее
См. в разделе Словарь, работающий поверх сети на основе сокетов операционной системы. Он может отправлять и получать сообщения, представленные в виде массивов байтов, и предлагает ряд различных вариантов «качества обслуживания», подходящих для различных сценариев. Он ориентирован на гибкость и производительность и предоставляет API в классе NetworkTransport.
Транспортный уровень поддерживает базовые службы для сетевого взаимодействия. Эти базовые службы включают:
Установление связей
Общение с использованием различных «качественных услуг»
Управление потоком
Базовая статистика
Дополнительные услуги, такие как связь через сервер ретрансляции или локальное обнаружение
Транспортный уровень может использовать два протокола: UDP для общего обмена данными и WebSockets для WebGLJavaScript API, который отображает 2D и 3D-графика в веб-браузере. Вариант сборки Unity WebGL позволяет Unity публиковать контент в виде программ JavaScript, использующих технологии HTML5 и API рендеринга WebGL для запуска контента Unity в веб-браузере. Подробнее
См. в Словарь. Типичный рабочий процесс для непосредственного использования транспортного уровня выглядит следующим образом:
Инициализация сетевого транспортного уровня
Настройка топологии сети
Создать хост
Начать общение (обработка подключений и отправка/получение сообщений)
Выключить библиотеку после использования
См. соответствующие разделы ниже, чтобы узнать о технических деталях каждого раздела. Каждый раздел содержит фрагмент кода для включения в сетевой сценарий.
Шаг 1. Инициализация сетевого транспортного уровня
При инициализации сетевого транспортного уровня вы можете выбрать между инициализацией по умолчанию, показанной в примере кода ниже (без аргументов), или указать дополнительные параметры, управляющие общим поведением сетевого уровня, такие как максимальное количество пакетов. размер и ограничение времени ожидания потока.
Чтобы инициализировать транспортный уровень с настройками по умолчанию, вызовите Init():
// Initializing the Transport Layer with no arguments (default settings)
NetworkTransport.Init();
To initialize the transport layer with your own configuration just add your configuration as a parameter to Init, as shown below.
// An example of initializing the Transport Layer with custom settings
GlobalConfig gConfig = new GlobalConfig();
gConfig.MaxPacketSize = 500;
NetworkTransport.Init(gConfig);
Пользоваться пользовательскими значениями Init
следует только в том случае, если у вас необычная сетевая среда и вы знакомы с конкретными необходимыми настройками. Как правило, если вы разрабатываете типичную многопользовательскую игру, в которую можно играть через Интернет, достаточно стандартных настроек Init
.
Шаг 2. Настройте топологию сети
Следующим шагом является настройка соединений между одноранговыми узлами. Топология сети определяет количество разрешенных подключений и используемую конфигурацию подключения. Если ваша игра должна отправлять сетевые сообщения, которые различаются по важности (например, низкая важность, например, случайные звуковые эффекты, по сравнению с высокой важностью, например, о том, набрал ли игрок очко), вы можете определить несколько каналов связи, каждый из которых имеет разное качество сообщений. уровень обслуживания, указанный в соответствии с конкретными типами сообщений, которые вы хотите отправить, и их относительной важностью в вашей игре.
ConnectionConfig config = new ConnectionConfig();
int myReliableChannelId = config.AddChannel(QosType.Reliable);
int myUnreliableChannelId = config.AddChannel(QosType.Unreliable);
Приведенный выше пример определяет два канала связи с разными значениями качества обслуживания. QosType.Reliable доставляет сообщение и гарантирует его доставку, а QosType.Unreliable отправляет сообщение быстрее, но без проверки доставки.
Вы также можете настроить свойства ConnectionConfig, чтобы указать параметры конфигурации для каждого подключения. Однако при установлении соединения от одного клиента к другому параметры должны быть одинаковыми для обоих подключенных одноранговых узлов, иначе соединение завершается ошибкой CRCMismatch ошибка.
Последний шаг настройки сети — определение топологии.
HostTopology topology = new HostTopology(config, 10);
В этом примере определяется топология хоста, допускающая до 10 подключений. Это те подключения, которые вы настроили на шаге 1.
Шаг 3. Создайте хост
Теперь, когда вы выполнили первые два шага предварительной настройки, вам нужно создать хост (открытый сокет):
int hostId = NetworkTransport.AddHost(topology, 8888);
В этом примере кода добавляется новый хост через порт 8888 и любые IP-адреса. Хост поддерживает до 10 подключений (вы настроили это на шаге 2). Это те подключения, которые вы настроили на шаге 1.
Шаг 4. Начните общение
Чтобы начать общение, вам необходимо установить соединение с другим хостом. Для этого вызовите Connect()
. Это устанавливает соединение между вами и удаленным хостом. Получено событие, указывающее, успешно ли установлено соединение.
Сначала подключитесь к удаленному хосту по адресу 192.168.1.42 через порт 8888. Возвращается назначенный connectionId
.
connectionId = NetworkTransport.Connect(hostId, "192.168.1.42", 8888, 0, out error);
После установления соединения будет получено событие ConnectEvent. Теперь вы можете начать отправку данных.
NetworkTransport.Send(hostId, connectionId, myReliableChannelId, buffer, bufferLength, out error);
После завершения подключения вызовите Disconnect()
, чтобы отключить хост.
NetworkTransport.Disconnect(hostId, connectionId, out error);
Чтобы проверить, были ли вызовы ваших функций успешными, вы можете преобразовать out error
в NetworkError а>. NetworkEror.Ok означает, что ошибок не обнаружено.
Чтобы проверить статус хоста, вы можете использовать две функции:
Для опроса событий из внутренней очереди событий вы можете вызвать
NetworkTransport.Receive(out recHostId, out connectionId, out channelId, recBuffer, bufferSize, out dataSize, out error);
Или NetworkTransport.ReceiveFromHost(recHostId, out connectionId, out channelId, recBuffer, bufferSize, out dataSize, out error);
Обе эти функции возвращают события из очереди; первая функция будет возвращать события с любого хоста, а переменной recHostId будет присвоен идентификатор хоста, с которого пришло сообщение, тогда как вторая функция возвращает события только с хоста, указанного предоставленным вами recHostId.
Один из способов опросить данные из Receive
— вызвать их в функции Update
;
void Update()
{
int recHostId;
int connectionId;
int channelId;
byte[] recBuffer = new byte[1024];
int bufferSize = 1024;
int dataSize;
byte error;
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: break;
case NetworkEventType.DataEvent: break;
case NetworkEventType.DisconnectEvent: break;
case NetworkEventType.BroadcastEvent:
break;
}
}
Есть 5 типов событий, которые вы можете получать.
NetworkEventType.Nothing: очереди событий нечего сообщать.
NetworkEventType.ConnectEvent: вы получили событие подключения. Это может быть либо успешный запрос на подключение, либо ответ на подключение.
case NetworkEventType.ConnectEvent:
if(myConnectionId == connectionId)
//my connect request was approved
else
//somebody else sent a connect request to me
break;
NetworkEventType.DataEvent: вы получили событие данных. Вы получаете событие данных, когда есть данные, готовые к получению. Если
recBuffer
достаточно велик для хранения данных, данные копируются в буфер. В противном случае событие содержит сетевую ошибку MessageToLong. В этом случае необходимо перераспределить буфер, указав больший размер, и снова вызвать функциюDataEvent
.NetworkEventType.DisconnectEvent: Установленное соединение разорвано или ваш запрос на подключение не выполнен. Проверьте код ошибки, чтобы узнать, почему это произошло.
case NetworkEventType. DisconnectEvent:
if(myConnectionId == connectionId)
//cannot connect for some reason, see error
else
//one of the established connections has disconnected
break;
- NetworkEventType.BroadcastEvent: указывает, что вы получили широковещательное событие и теперь можете вызывать GetBroadcastConnectionInfo и GetBroadcastConnectionMessage для получения дополнительной информации.
Поддержка WebGL
Вы можете использовать WebSockets в WebGL, однако веб-клиенты могут подключаться только к хостам, они сами не могут быть хостами. Это означает, что хост должен быть автономным плеером (только для Win, Mac или Linux). Для конфигурации на стороне клиента все шаги, описанные выше (включая топологию и настройку), одинаковы. На сервере вызовите следующее:
NetworkTransport.AddWebsocketHost(topology, port, ip);
Приведенный выше IP-адрес должен быть конкретным адресом, который вы хотите прослушивать, или вы можете указать null в качестве IP-адреса, если хотите, чтобы хост прослушивал все сетевые интерфейсы.
Сервер может одновременно поддерживать только один хост WebSocket, но одновременно может обрабатывать и другие общие хосты:
NetworkTransport.AddWebsocketHost(topology, 8887, null);
NetworkTransport.AddHost(topology, 8888);