Создание сервера для Российских онлайн ММО игр ч. 8 — Клиентская часть на Unity

Разобравшись в архитектуре сервера, реализовав механизм простого расширения его функционала путем добавления пользовательского кода через WEB админ панель и игровых локаций захотелось наконец посмотреть как бы это все работало и выглядело в игре.

Т.к. сервер для игры является авторитарным то клиентская часть должна была содержать:

  • интерфейс UI с разнообразными меню и кнопочками, джойстиком
  • клиентскую часть подключения к серверу по протоколу websocket (о котором я писал ранее) для отправки команд и получения ответа во время игры
  • возможность работать по http протоколу (для первичной регистрации, авторизации и загрузки на клиент графики и желательно асинхронно)
  • из желательного было так же поддержка тайловых карт из коробки

Начать решил с 2D онлайн игры с перспективой перехода к 3D. Т.к. ранее я не имел дело с игровыми движками то выбрал наиболее популярный — Unity который имеет хорошую документацию в т.ч. на русском языке, множество обучающих видео, да и главная страница их сайта мотивировала выбрать именно этот движок использующий язык программирования С# для написания кода помимо встроенного инструментария для работы со сценами, анимацией, картами, камерой и др.

главная страница сайта <a href="https://api.dtf.ru/v2.8/redirect?to=https%3A%2F%2Funity.com%2Fru&postId=1865909" rel="nofollow noreferrer noopener" target="_blank">https://unity.com/ru</a>
главная страница сайта https://unity.com/ru

В своей первой статье я рассказывал, что информации о том как сделать свою онлайн игру без использования платных сервисов (Photon, FireBase, PlayFab, Mirror и др.) весьма мало, а еще меньше тех, что могут выдержать нагрузку более пары десятков человек и то что останется будет на английском языке. Так что в России я с какой то стороны первопроходец реализующий целый сервис с API и нужно не упасть в грязь лицом реализуя примеры интеграции.

Я бы хотел сказать что первым делом я разработал API, документацию по работе админ панели и на базе этого создал клиент — но это не так и по факту было в обратной последовательности: вступая на этот неизвестный путь я вообще не понимал чего следует ждать, десятки раз переделывал клиентскую и серверную часть — постоянно что то не устраивало (как по архитектуре кода, так и по скорости) и так прошло около 4х месяцев и в очередной раз сидя ночью в номере отеля в Африке я анонсировал первую рабочую версию API по работе с сервером и первые примеры добавления игровых механик в сервер через WEB.

Можно было создать метод API, описать через Lua, Java Script или PHP (на выбор, подробнее писал об этом тут) во встроенной IDE код что этот метод будет делать на сервере, сделать этот метод публичным (все это через WEB админ панель) и вызвать с клиентского приложения (который к тому моменту был никак не описан и не структурирован). Для демонстрации метод добавлял на карту Гоблина.

гоблин добавляется на сервере и в клиенте в режиме online по вызову метода API
гоблин добавляется на сервере и в клиенте в режиме online по вызову метода API

Так же я заранее позаботился о том, что нужен инструмент отладки запросов по API (аналог swagger или postman, но в рамках той же админ панели), а т. к. Unity может портировать игры в том числе и на браузеры (webgl игры которые можно в т.ч. размещать на независимых от сервера сайтах) стало возможным не только слать запросы и видеть ответ, но и тут же наблюдать за тем что происходит в игре, выглядело это так:

панель загрузки браузерной версии игры Unity
панель загрузки браузерной версии игры Unity
пример отладочной панели с игрой на webgl unity
пример отладочной панели с игрой на webgl unity

Сделав это пришла пора привести в порядок код клиентской части игры и реализовать все в виде плагина на Unity. Для себя я выделил следующие важные факторы

  • Код должен представлять собой плагин для Unity и содержать функционал приемки и отправки пакетов.
  • Структура кода игры должна повторять структуру плагина расширяя его классы дополнительным функционалом.
  • Использовать ООП (объектно‑ориентированный подход) т. к. я уже привык с ним работать в PHP (хотя бы постараться его применять в коде игры).
  • Для описания запросов к серверу и ответов использовать «структуры» (позже из за проблем с кодированием и декодирования json struct пришлось переделать в обычные классы но их назначение осталось прежним).
  • На каждом «префабе» в Unity (то есть на любом игровом объекте с которым можно взаимодействовать) должен быть «повешен» фаил — класс который принимает от главного контроллера пакетов пакет именно этого префаба и обновляет данные (например изменение позиции, жизней, маны, запуск новой анимации и т. д).
  • Должны быть из коробки решены проблемы с которыми сталкиваются разработчики при разработке онлайн игры (интерполяция, экстраполяция, поддержка работы с websocket соединением в версии для пк, мобильных устройств и браузеров и связанные с последней проблемы, такие как ввод теста, изменение размера окна, потеря фокуса и т. д.).
  • Поддержка функционала бесшовного мира сервера и переход между локациями.
  • В проекте должно быть 2 сцены (сцена авторизации/регистрации и пустая сцена, где на лету меняется карта и префабы на ней).
  • Readme к папкам и файлам проекта.

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

пример фала readme клиентской части онлайн игры
пример фала readme клиентской части онлайн игры

Если кому то станет более интересна тема интеграции в Unity взаимодействия с серверным API в данной реализации я так же подготовил плейлист на своем канале Youtube где я объясняю как что работает сам плагин (хотя при разработке игры предполагается что разработчику не нужно углубляться в это).

В следующих статьях я расскажу как именно реализовываются игровые механики на сервере и в клиенте, а в моем профиле вы найдете ссылки на другие статьи проекта mmogick.ru.

История:

77
2 комментария

Структура кода игры должна повторять структуру плагина расширяя его классы дополнительным функционалом.

Струтктура кода игры, как сильная и независимая, никому и ничего не должна, особенно не должна подстраиваться ни под один из кучи плагинов, используемых в игре

Потому что в класическом виде игры делают оффлайн и программист волен делать как и что ему хочется в клиенте. А если он делает онлайн и пользуется сторонними сервисами (не важно какими) - он должен подстраиваться под эти сервисы или тратить время на написание своего решения и как показано в видео одного такого проекта описанного в моей первой статье - не всегда удачно

В дополнение скажу что "должна" имеется в виду для работы с плагином который сделал я в парадигме Объектно Ориентированного Подхода а конкретно в части полиморфизма и наследования классов что позволит изменять в том числе поведение плагина не меняя его код (расширяя его) , можно переделать под процедурный полагаю и подгружать библиотеки что шлют команды на сервер где и описаны все игровые механики (клиент по сути содержит лишь UI интерфейс и пока временно анимацию , но в будущем и они будут храниться и догружаться как карты в клиент)