Войти
UnityФорумСеть

Unity, свой сетевой движок

#0
0:20, 20 июля 2019

Всем доброго времени суток, уважаемые разработчики и прочие форумчане, читающие этот текст)
Делаю игру на Юнити, игра в 2д. Делаю игру для начала с целью научиться, а потом посмотреть на готовый результат, и по возможности/желанию допилить и может даже распостранить. Всё-таки имею нездоровую страсть к мультиплееру, по этому с первых секунд создания игры, только и думал о нём)
Как известно, делать игру с мультиплеером надо на сетевом движке. Есть UNet (встроенный в Юнити), но во-первых: его уже упраздняют (https://support.unity3d.com/hc/en-us/articles/360001252086-UNet-Deprecation-FAQ), во - вторых: Всё-таки очень интересно попробовать написать сетевую часть именно самому. Сразу скажу, в сетях и т.п. я особо хорошо не разбираюсь, но именно с этой целью я и взялся за разработку сетевого движка, пусть он будет пока-что простенький, но я хоть буду понимать как и что работает лучше, чем сейчас. Ближе к делу: На данный момент пришлось убрать из игры все анимации и т.д., что бы было проще тренироваться в написании сетевого движка. С чего я начал: Написание Клиента - Сервера (сначала сделал всё на ТСП, потом переделал под ЮДП). Клиент - сама игра, Сервер - отдельная приложуха на С#, запущенная на другом компе. Сейчас, когда игра запускаеться, можно управлять персонажем клавишами A, D. На персонаже висит скрипт, который содержит такую структуру:

 public struct TransmissionData
        {
            public string PlayerName;

            public float X;

            public float Y;

            public float Z;

            public bool Shooting;

            public int HP;

            public DateTime time;

        }
  При нажатии на клавиши движения, в функции Update, для X,Y и Z присваиваеться значение, потом конвертируеться в JSON, и строкой летит на сервер по ЮДП. Сервер это принимает, логирует, и отправляет эту же строку обратно, и только тогда персонаж двигаеться. Т.е.: Нажимаем кнопку движения——> На сервер отправилась строка (структура TransmissionData) —--> сервер выдает её обратно——> клиэнт принимает, и персонаж двигаеться. та же самая процедура со стрельбой. Просто я так сделал, что бы добиться лучше синхронизации клиента и сервера (как мне кажеться), но увеличив тем самым "пинг". Хочу добавить второго персонажа, что бы хотя бы бегать вдвоём по карте, вот только как это сделать лучше с точик зрения сетевой части? Так же отправлять строку на сервер, а взамен получать громадную строку о местоположении и других параметрах ВСЕХ остальных игроков на карте? Но ведь там может быть очень много информации, и сигнал так быстро не обработаеться. Ещё был вопрос на будущее: а как быть с анимациями? отправлять их так же как я делаю со стрелбьой?))) Меняя false на true... Может у когото есть опыт, подскажите пожалуйста, как лучше реализовать это всё дело. Мне действительно нужно сейчас найти более ли менее правильный путь))) Заранее, спасибо большое!


#1
8:55, 20 июля 2019

CeSium
> Так же отправлять строку на сервер, а взамен получать громадную строку о
> местоположении и других параметрах ВСЕХ остальных игроков на карте? Но ведь там
> может быть очень много информации, и сигнал так быстро не обработаеться.
добро пожаловать в реальный мир :), используй libzip для сжатия

CeSium
> . Ещё был вопрос на будущее: а как быть с анимациями? отправлять их так же как
> я делаю со стрелбьой?)))
слать на сервер команду: игрок_айди.выстрел(х,у) — ответ сервера: игрок_айди.попал\промазал
анимации делать только в клиенте.. сервер должен прислать ответ:игрок_айди.перемещение(х1,у1,х2,у2),  а клиент должен включить анимацию и показать как персонаж двигается...


на сервере должна быть реализована полная карта уровня + состояния всех игроков, а сообщения между клиентов и серверов сделать по принципу АПИ (где пересылаются функции(пример:игрок_айди.выстрел(х,у)))

#2
9:47, 20 июля 2019

AizbegtTeam
Окей, спасибо огромное за информацию!)
Только есть вопросик, libzip использовать для сжатия передаваемой информации? Просто тогда на "разжатие" будет тоже уходить время, или оно там не значительное? (я просото очень боюсь высокого пинга)

#3
11:03, 20 июля 2019

CeSium
> Просто тогда на "разжатие" будет тоже уходить время,
не знаю сколько
CeSium
> я просото очень боюсь высокого пинга
сделай сразу чтобы работало, потом будешь оптимизировать для быстроты

#4
11:14, 20 июля 2019

AizbegtTeam
Окей, спасибо вам огромное!)
Буду пробовать)

#5
11:42, 20 июля 2019

JSON для рилтайм сети подходит плохо, для таких целей нужно пользоваться самопальным сериализатором свойств в структуру. А чтобы не было "у меня забился канал" нужно использовать тресхолды, и не отправлять объекты, которые не изменились, или изменились незаметно для клиента(актуально для физики) и разделить протокол на два канала: unrealiable - канал для пакетов, которым не требуется гарантия доставки и reliable - надёжный канал, который гарантированно доставит пакет. В TCP для рилатйм сети тоже ничего плохого нет, если есть нормальный батчинг пакетов, и нагрузка не слишком тяжёлая.

Синхронизация анимаций - вещь отдельная. Кто-то стейт всей анимации синхронизирует, а кому-то достаточно передать пакет аля "объект a начал проигрывать анимацию b".

#6
11:53, 20 июля 2019

monobogdan
Вот у меня была идея, на сервере для каждого персонажа реализовать "область догрузки". Т.е. если в какой-то области от персонажа есть другие игроки, то только в таком случае передавать их данные клиенту. Что бы небыло такого, что игрок1 находясь на одном конце (довольно большой) карты, загружал игроков на другом конце карты. Передавать в таком случае нужно разве что - команду для проигрывания звука, ибо я бы хотел что бы звук имел не последнее место в моей игре). Тогда канал действительно не будет забиваться кучей одинаковых сообщений. На счёт анимаций - действительно, лучше передать команду для проигрывания анимации.
Спасибо огромное за совет!)

#7
12:08, 20 июля 2019

CeSium
Техник много есть, зависит от задачи. Кто-то объекты по видимости куллит(в основном, для защиты от читов), кто-то стриминг реализовывает.

UnityФорумСеть

Тема в архиве.