18

Unity UDP P2P (напрямую и через собственный релэй)

И так, вам захотелось добавить сетевуху в вашу игру, и вы не хотите фотон (например потому что нас сейчас отключают везде где могут :) )


Когда-то я сделал ставку на оклусовскую сетевуху для нашей игры, и на сегодняшний день это вылилось в переписывание половины игры (и ф*йс*ук забанен, и сетевуху свою они сворачивают), но так же наша команда написала свой собственный релэй-сервер на C# (http://gitlab.sa-wd.ru/DarkanSoince/networking/-/tree/v3).


Как писать.


Шишек набито достаточно, так что вот вам описание на пальцах как делать сетевуху:

1) Пакет из байтов для отправки делаем под 500-1200 байт (есть мнение про 500, я использую 1000)

2) В пакет влазит еще? - суем, а не отправляем отдельным пакетом
3) Не влазит? отправляем и забиваем новый пакет вне таймера
4) Отправляем по таймерам, а не по кадрам (хотя тут как хотите)

5) Поскольку все пакеты одинаковые, не пересоздаем пакет, а заменяем в нём данные перед отправкой

6) Reliable пакеты отправляем только когда надо знать что пакет дошел (например, отправить старт игры - релиэйбл, движение - не релиэйбл)

7) Если вам надо менять состояние чего-либо, что меняется часто (например владелец предмета), посылаем это состояние в каждом пакете, а не отдельной командой для смен состояния (например вместе с движением).


Простой путь - смотрите тут примеры - http://gitlab.sa-wd.ru/DarkanSoince/networking/-/tree/v3/Program

Смените IP на 127.0.0.1 тут - http://gitlab.sa-wd.ru/DarkanSoince/networking/-/blob/v3/Networking/ClientProgram.cs

Запускать сначала мастер, потом два клиента.

cd .\Program\Master\
dotnet run --framework net6.0
cd .\Program\Client\
dotnet run --framework net6.0

Сервер запустит и после отключения клиентов убьет мастер.


Сложный путь. Штош, перейдем к коду.


Мы используем гугл-протобаф для сериализации/десериализации и первым делом вам надо будет взять и понаписать файлов в /Proto/Event (смотрим код репы, читаем тут https://developers.google.com/protocol-buffers/docs/proto3#scalar) про каждый тип пакета, который вы вообще умеете отправлять.


Допустим что мы хотим что бы персонаж ходил

ProtoTransform.proto (пример названия файла в /Proto/Event)
syntax = "proto3";
package protos;
message ProtoTransform {
int32 netId = 1;  // что двигаем
float positionX = 2; 
float positionY = 3; 
float positionZ = 4;
float rotationX = 5; 
float rotationY = 6; 
float rotationZ = 7; 
float rotationW = 8; 
int32 sequence = 9; // счетчик, который всегда идет вверх
float velocityX = 10; 
float velocityY = 11; 
float velocityZ = 12; 
int32 playerId = 14; 
float angularVelocityX = 15; 
float angularVelocityY = 16; 
float angularVelocityZ = 17;
}

Зачем sequence - что бы два раза не делать одно и то же если пакет пришел позже следующего (а он может и прийти не по порядку и не прийти вовсе, просто при отправке его плюсуем)


Тыкаем build proto.bat, всё, магия готова и наш протофайл сбилжен :)


Тыкаем unity package.bat и у нас в папке /UnityPackage появится билд сетевухи


Запускаем юнити

Window -> package manager -> + -> add package from disk -> папка /UnityPackage/package.json


// Это будет наш нетворкинг. Да, весь в одном файле :)
using SAWD.Networking;
public class SAWDNet : MonoBehaviour {
public enum MessageType {
Transform = 100, // это что бы не перебивать значения из скомпилленого файла
LuboeDrudoe = 101
}
Protos.ProtoTransform protoSendTransform = new Protos.ProtoTransform();
private void Start() {
clientProgram = new ClientProgram();
clientProgram.Start();
clientProgram.Enqueue_ToMaster("default"); // http://gitlab.sa-wd.ru/DarkanSoince/networking/-/blob/v3/Program/Master/.env (этот дэфаулт - QUEUE_default= отсюда, а не из Name, обязательно законфигить под себя!)
// входящий пакет с трансформом
Net.On((int) MessageType.Transform, (point, data) => { // входящий трансформ
var protoOnReceiveTransform = ProtoTransform.Parser.ParseFrom(data.Data);
// protoOnReceiveTransform вот ваш пакет данных, делайте что хотите с ним
});
// я подключился к серверу
Net.On((int) Net.MessageType.Server_Connected, ((point, data) => {
Debug.Log("-Server_Connected- SAWDNet.localPlayerId:" + SAWDNet.localPlayerId);
var connected = Proto.Event.Connected.Parser.ParseFrom(data.Data);
Debug.Log("-Server_Connected- connected:" + connected);
foreach (var userId in connected.Ids) {
Debug.Log("-Server_Connected- userId:" + userId);
//RemoteUser.CreateUser(userId);
// создайте тут юзера (аватар и тд с ид userId). Тут могут быть дубли, создавайте один раз на юзера!
}
}));
// кто-то подключился к серверу после меня
Net.On((int) Net.MessageType.Server_AnotherUserConnected, ((point, data) => {
var connected = Proto.Event.Connected.Parser.ParseFrom(data.Data);
//RemoteUser.CreateUser(connected.Id);
Debug.Log("-Server_AnotherUserConnected- connected:" + connected);

SendTransform(); // один раз отправим трансформ новому подключившемуся

}));

}


private void Update()

{
Net.Update();
if (!Debug.isDebugBuild) return;
while (Net.Logs.TryDequeue(out var log)) {
Debug.Log(log); // у сетевухи разные треды, читаем лог в главном треде
}
}


private void SendTransform(){
// отправка один раз для примера
protoSendTransform.PositionX = lastLocalPosition.x;
protoSendTransform.PositionY = lastLocalPosition.y;
protoSendTransform.PositionZ = lastLocalPosition.z;
Net.Broadcast(GroupType.Client | GroupType.Server, (int) SAWDNet.MessageType.Transform, protoSendTransform , true); // тру значит релиэйбл, будет долбить пока не передаст, ВАМ тут тру не надо, вам надо фолс :)
}


Запускаем сервер


cd .\Program\Master\
dotnet run --framework net6.0

(проверяем что IP мастер сервера в клиенте указан верно, иначе ничего не подключится! http://gitlab.sa-wd.ru/DarkanSoince/networking/-/blob/v3/Networking/ClientProgram.cs)


Запускаем пару клиентов. После коннекта они отправят и получат protoSendTransform или через сервер или напрямую, если они смогут подключиться.


Может быть когда-нибудь я осилю написать нормальную документацию.

Правила сообщества

ОБЩИЕ ПРАВИЛА:

- Уважайте чужой труд и используйте конструктивную критику

- Не занимайтесь саморекламой, пишите качественные и интересные посты

- Никакой политики


СТОИТ ПУБЛИКОВАТЬ:

- Посты о Вашей игре с историей её разработки и описанием полученного опыта

- Обучающие материалы, туториалы

- Интервью с опытными разработчиками

- Анонсы бесплатных мероприятий для разработчиков и истории их посещения;
- Ваши работы, если Вы художник/композитор и хотите поделиться ими на безвозмездной основе

НЕ СТОИТ ПУБЛИКОВАТЬ:

- Посты, содержащие только вопрос или просьбу помочь
- Посты, содержащие только идею игры

- Посты, единственная цель которых - набор команды для разработки игры

- Посты, не относящиеся к тематике сообщества

Подобные посты по решению администрации могут быть перемещены из сообщества в общую ленту.

ЗАПРЕЩЕНО:

- Публиковать бессодержательные посты с рекламой Вашего проекта (см. следующий пункт), а также все прочие посты, содержащие рекламу/рекламные интеграции

- Выдавать чужой труд за свой

Подобные посты будут перемещены из сообщества в общую ленту, а их авторы по решению администрации могут быть внесены в игнор-лист сообщества.


О РАЗМЕЩЕНИИ ССЫЛОК:

Ссылка на сторонний ресурс, связанный с игрой, допускается только при следующих условиях:

- Пост должен быть содержательным и интересным для пользователей, нести пользу для сообщества

- Ссылка должна размещаться непосредственно в начале или конце поста и только один раз

- Cсылка размещается в формате: "Страница игры в Steam: URL"

Темы

Политика

Теги

Популярные авторы

Сообщества

18+

Теги

Популярные авторы

Сообщества

Игры

Теги

Популярные авторы

Сообщества

Юмор

Теги

Популярные авторы

Сообщества

Отношения

Теги

Популярные авторы

Сообщества

Здоровье

Теги

Популярные авторы

Сообщества

Путешествия

Теги

Популярные авторы

Сообщества

Спорт

Теги

Популярные авторы

Сообщества

Хобби

Теги

Популярные авторы

Сообщества

Сервис

Теги

Популярные авторы

Сообщества

Природа

Теги

Популярные авторы

Сообщества

Бизнес

Теги

Популярные авторы

Сообщества

Транспорт

Теги

Популярные авторы

Сообщества

Общение

Теги

Популярные авторы

Сообщества

Юриспруденция

Теги

Популярные авторы

Сообщества

Наука

Теги

Популярные авторы

Сообщества

IT

Теги

Популярные авторы

Сообщества

Животные

Теги

Популярные авторы

Сообщества

Кино и сериалы

Теги

Популярные авторы

Сообщества

Экономика

Теги

Популярные авторы

Сообщества

Кулинария

Теги

Популярные авторы

Сообщества

История

Теги

Популярные авторы

Сообщества