Базовая связь клиент-сервер с использованием Unity и gRPC

Обзор

gRPC имеет множество преимуществ, включая встроенную поддержку HTTP / 2, которая, в свою очередь, позволяет мультиплексировать двунаправленные потоки. Однако это связано с некоторой сложностью и все еще не так развито, как, скажем, REST. Так что есть еще несколько сценариев, в которых REST может быть лучшим выбором.

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

Эта статья была написана как часть Рождественского календаря Акацуки на 2019 год

Что мы будем делать

В этом посте мы создадим простой двунаправленный канал связи между клиентом Unity (C #) и сервером gRPC (Golang).

  • У нас будет одна сцена в Unity, которая отображает 3D-объект на базовой плоскости.
  • Клиент запросит у сервера случайный цвет и будет использовать результат для изменения цвета 3D-объекта.

Для простоты мы не будем рассматривать потоки gRPC в этом посте, но сделаем это в ближайшем будущем, так что следите за обновлениями!

Предпосылки

Прежде чем мы начнем, вот некоторые предварительные условия для этого поста.

Знания

  • Было бы полезно знать базовые знания Unity или другого игрового движка.
  • Опыт программирования от базового до среднего (C # и / или Go было бы неплохо, но не обязательно)
  • Базовое понимание gRPC (этого должно быть достаточно)
  • Знакомство с инструментами командной строки
  • Открытый разум :)

Инструменты

  • Unity 2019.3.x или новее (я использую 2019.3.0f1)
  • Go 1.13.x или новее (я использую 1.13.4)
  • Ваши любимые IDE или текстовый редактор

Также несколько замечаний

  • gRPC для Unity все еще является экспериментальным, поэтому он может не подходить для развертывания в производственной среде (пока)
  • Я буду использовать OS X (Mac) для этого поста, поэтому, хотя команды могут немного отличаться для пользователей Windows, они должны быть достаточно похожими, чтобы следовать

Итак, давайте начнем! :)

Базовая настройка Unity

Сначала мы создадим базовую плоскость с кубом и кнопкой пользовательского интерфейса, которая будет триггером для изменения цвета куба. Если вы хорошо знакомы с Unity, можете сразу перейти к тому, где мы начнем писать скрипт для кнопки.

Сначала создадим базовый клиент Unity

  • Создайте новый 3D-проект в Unity, который должен поставляться с SampleScene по умолчанию, который включает основную камеру и направленный свет.
  • Измените имя по умолчанию SampleScene на Main в иерархии проекта.
  • Под сценой добавьте 3D-плоскость (из меню GameObject). Было бы неплохо сбросить Position и Rotation на 0 в разделе Transform и установить Scale на 1 по всем осям. Также установите белый цвет для плоскости (если это другой цвет). Это сделано для того, чтобы наш цветной объект было легче увидеть с белым контрастом.

  • Также установите положение Основная камера (X, Y, Z) на (0, 1, -5), чтобы мы могли видеть центр плоскости, как показано в разделе предварительного просмотра камеры.

  • Затем добавьте игровой объект 3D Cube в сцену из иерархии. Как и раньше, сбросьте преобразования и установите положение (X, Y, Z) на (0, 0,5, 0)
  • Также создайте новый материал CubeMat для куба и примените его как новый материал куба (в Mesh Renderer)
  • На этом этапе у вас должно получиться что-то вроде этого

Теперь давайте добавим кнопку пользовательского интерфейса

Мы будем использовать это позже, чтобы запросить случайный цвет с сервера gRPC и назначить его кубу.

  • В Иерархии создайте новый элемент пользовательского интерфейса Button - ›TextMeshPro. Причина, по которой мы хотим выбрать это вместо обычной кнопки, заключается в том, что компонент текста по умолчанию Unity имеет проблемы с масштабированием и не отображает должным образом для разных разрешений. Вы можете прочитать больше об этом здесь". TextMesh Pro теперь бесплатен и по умолчанию интегрирован в Unity! Поэтому я рекомендовал использовать его, когда это возможно.

  • Если вы видите диалоговое окно об импорте TMP Essentials, просто нажмите на него.

  • Установите якоря кнопки в центр вверху, а для параметра (Ширина, Высота) установите значение (200, 50). Также под элементом Button установите привязки Text (TMP) для растягивания и измените текст на Randomize!. Вы также можете поиграть с размером, чтобы он соответствовал кнопке (a размер 25 вроде работает)

Фу ... наконец-то мы можем начать писать код!

  • Создайте новый каталог Scripts в разделе Assets, создайте пустой GameObject и добавьте к нему новый сценарий C # с именем ColorRandomizer.cs
  • Скрипту потребуется ссылка на Материал, который мы создали ранее, и общедоступный метод для изменения цвета, который мы свяжем с обработчиком OnClick кнопки Randomize Button.
  • Добавьте приведенный ниже код в файл ColorRandomizer.cs, который вы только что создали.
  • В приведенном выше коде вы заметите, что все, что мы делаем в GetColor (), выводит сообщение в Debug.Log () и устанавливает цвет на Красный. Не волнуйтесь, мы добавим вызов на сервер позже
  • Теперь сохраните ColorRandomizer.cs, и вы должны увидеть поле в инспекторе для добавления материала. Давайте добавим CubeMat в это поле

  • А теперь давайте проверим! Нажмите Играть на вкладке "Игра" и нажмите кнопку Случайно, чтобы убедиться, что цвет изменился.
  • Затем давайте создадим сервер

Создать сервер

Определение прото-файла

Чтобы создать сервер, нам сначала нужно создать файл прототипа определения службы gRPC.

По сути, это интерфейс, определяющий сообщения и сервисы, которые мы будем использовать в нашем проекте.

В нашем случае клиент и сервер должны общаться в одном сообщении.

Когда игрок нажимает кнопку на клиенте, мы хотим отправить текущий цвет объекта на сервер и получить случайный цвет в качестве ответа

Итак, давайте посмотрим, как будет выглядеть прото-файл для этого.

Сохраните прото-файл как, скажем, color.proto в своем домашнем каталоге, и давайте сгенерируем код сервера.

Protobuf и gRPC

  • Сначала давайте установим protobuf с помощью brew для OSX (пользователи Windows должны иметь возможность получить выпуск здесь)
brew install protobuf
  • Затем давайте установим gRPC.
go get -u google.golang.org/grpc
  • И, наконец, генераторы протоколов для Go
go get -u github.com/golang/protobuf/protoc-gen-go
  • Чтобы все было в порядке, давайте сначала создадим необходимые каталоги. Предполагая, что ваш прото-файл находится в ~ / color.proto, давайте переместим и его
mkdir -p ~/unity-grpc-colorgen/grpc/{client,server}
mv ~/color.proto ~/unity-grpc-colorgen/grpc/
  • Теперь приступим к генерации!
cd ~/unity-grpc-colorgen
protoc -I grpc/ --go_out=plugins=grpc:grpc/server color.proto
  • Это должно создать файл color.pb.go в папке ~ / unity-grpc-colorge n / grpc / server, который содержит весь код, который мы нужно использовать protobuf в нашем проекте
  • Давайте скопируем этот файл и воспользуемся им для создания нового проекта Go.
  • Создайте там файл main.go, который будет содержать основную логику подключения для сервера.
  • Как только это будет сделано, давайте запустим сервер!

Обновите клиент для использования gRPC

  • Теперь давайте сгенерируем файлы на стороне клиента из файла color.proto.
cd ~/unity-grpc-colorgen
protoc -I grpc/ --csharp_out=grpc/client --grpc_out=grpc/client --plugin=protoc-gen-grpc=/usr/local/bin/grpc_csharp_plugin color.proto

Примечание. Если вы используете Windows и на этом этапе у вас возникли проблемы с компиляцией, пожалуйста, проверьте этот комментарий

  • Это должно создать 2 файла - Color.cs и ColorGrpc.cs в папке ~ / unity-grpc-colorgen / grpc / client
  • Скопируйте оба файла в каталог Unity Assets / Scripts.
  • Теперь давайте воспользуемся клиентскими файлами gRPC и обновим наши клиентские скрипты!
  • Сначала создайте файл ColorClient.cs в каталоге Unity Assets / Scripts и добавьте приведенный ниже код.
  • Давайте также обновим скрипт ColorRandomizer.cs (см. Ниже).
  • Сценарий ColorClient.cs отвечает за логику gRPC, а ColorRandomizer.cs управляет преобразованием полезной нагрузки Color.

Наконец-то пришло время попробовать!

  • Запустите сервер gRPC из каталога проекта Go
go run main.go
  • Запустите свой клиент на Unity и нажмите кнопку Произвольно!

  • В журналах сервера также отображаются сообщения, поступающие от клиента.

Ура работает !!! :)

Резюме

Мы установили базовую двунаправленную связь gRPC между сервером Go и клиентом Unity.

Полный исходный код, использованный для этого проекта, можно найти здесь.

Спасибо, что прочитали! Увидимся снова в следующем приключении :)