# Unity — Начало работы

Учитесь на практике и разверните свой первый выделенный сервер на Edgegap. К концу этого руководства вы бесплатно развернёте выделенный сервер с Edgegap.

{% embed url="<https://youtu.be/4FR04V4YEUk>" %}

## ✔️ Подготовка

<details>

<summary><a href="https://github.com/edgegap/edgegap-unity-plugin">Установите плагин Quickstart для выделенных серверов Unity от Edgegap</a></summary>

</details>

{% hint style="info" %}
**Уверены в сборках своего сервера?** Перейдите к [#customize-server-image](#customize-server-image "mention") или [Расширенные возможности](/ru/learn/advanced-features.md) для подробностей.
{% endhint %}

## ⚙️ 1. Подключить аккаунт

☑️ Войдите в систему и убедитесь, что в консоли Unity нет новых ошибок, связанных с плагином Edgegap.

✅ Теперь можно перейти к следующему шагу.

<details>

<summary>Устранение неполадок и FAQ</summary>

`!Success: 400 BAD REQUEST - POST | https://api.edgegap.com/v1/wizard/init-quick-start - {"message": "Браузер (или прокси) отправил запрос, который этот сервер не смог понять."}`

* Если вы установили его, скопировав ZIP-файл, или использовали пример проекта с копией плагина, установленной таким образом, вам потребуется вручную установить зависимости пакета, включая библиотеку Newtonsoft JSON, см. [официальному репозиторию плагинов](https://github.com/edgegap/edgegap-unity-plugin/tree/main?tab=readme-ov-file#instructions-1).
* Свяжитесь с нами на [Discord-сообществе](https://discord.gg/NgCnkHbsGp) за помощью, если это не так.

</details>

## 🔧 2. Собрать игровой сервер

Независимо от того, используете ли вы Windows, Mac или Linux-машину, вам **нужно собрать сервер для Linux runtime**, поскольку большинство облачных провайдеров сейчас (включая Edgegap) работают на Linux. Не волнуйтесь, для этого с нашим плагином не требуются знания Linux.

☑️ **Проверьте, что вы установили необходимые инструменты сборки Unity для Linux.**

☑️ Измените Build Settings, чтобы **убедиться, что все необходимые игровые сцены включены**.

{% hint style="info" %}
**Опытные пользователи Unity** — при желании измените [Unity Build Settings](https://docs.unity3d.com/Manual/BuildSettings.html). Внимание! Это может сломать вашу сборку.
{% endhint %}

☑️ По желанию: добавьте специфичный для netcode скрипт для проверки порта и инициализации среды в начальную сцену сервера через меню Edgegap Server Hosting (правый клик / :heavy\_plus\_sign: в окне Hierarchy).

<figure><img src="/files/d1e017469bc61e47646a0fb11d800cf488551f97" alt="" width="360"><figcaption></figcaption></figure>

{% hint style="info" %}
Как только вы выполните шаг [#id-6.-deploy-a-server-on-edgegap](#id-6.-deploy-a-server-on-edgegap "mention"), скрипт проверки порта запишет предупреждение, если адрес netcode или порты не совпадают с вашим [сопоставлением портов версии приложения](/ru/learn/orkestraciya/application-and-versions.md#other-parameters-optional) .
{% endhint %}

{% hint style="success" %}
Сборки сервера должны использовать адрес `0.0.0.0`  и порт `7777`  в вашем транспорте netcode. Если вы настраиваете порт, укажите то же самое в ваших [Приложения и версии](/ru/learn/orkestraciya/application-and-versions.md#port-mapping) после того как вы [#id-5.-upload-to-edgegap](#id-5.-upload-to-edgegap "mention").
{% endhint %}

☑️ Когда вас устроит конфигурация, нажмите **Собрать сервер**, дождитесь завершения процесса и убедитесь, что в консоли Unity нет новых ошибок. Выполнение этого шага приведёт к тому, что **в корне проекта появится новая папка** - `Builds/EdgegapServer/ServerBuild` .

✅ Теперь можно перейти к следующему шагу.

<details>

<summary>Устранение неполадок и FAQ</summary>

Unity: единственные поддерживаемые автономные цели — Windows x64 и OSX с OpenXR.

* Откройте Packages и отключите OpenXR перед сборкой сервера.
* Плагин OpenXR требуется только для клиентов и несовместим со сборками Linux-сервера. Исключая его из сборок сервера, вы не теряете никакой функциональности.

</details>

## 🐋 3. Контейнеризировать сервер

Работа в команде разработчиков означает совместное использование кода. Когда что-то идёт не так, последняя фраза, которую вы хотите услышать, — «у меня работает». Игровые серверы должны надёжно работать на любой машине, поскольку успешные игровые серверы будут работать на тысячах серверных машин по всему миру.

Чтобы помочь сделать ваш сервер надёжным, мы используем Docker — программное обеспечение виртуализации, которое гарантирует, что все зависимости кода сервера вплоть до уровня операционной системы всегда будут абсолютно одинаковыми, независимо от того, как и где запускается сервер.

☑️ Пока что начните с нажатия **Проверить** кнопки, чтобы убедиться, что вы завершили [Инструменты разработчика](/ru/unity/developer-tools.md#usage-requirements).

☑️ Вы можете настроить следующие параметры (или оставить значения по умолчанию):

* **Путь сборки** — это относительный путь к артефакту сборки сервера; пока оставим значение по умолчанию.

{% hint style="warning" %}
**Храните сборки внутри папки проекта**, Docker принимает только относительные пути сборки относительно корня проекта.
{% endhint %}

* **Имя образа** — это уникальный идентификатор на ваш выбор, которым помечается сборка сервера перед публикацией.
  * Обычно сюда включают название игры — например, «my-game-server».
* **Тег образа** — это идентификатор, указывающий на конкретную версию вашего образа.
  * Термин «артефакт сборки» иногда используется для обозначения конкретной версии вашего образа.
  * Для тегирования отлично подходят метки времени, например `2024.01.30-16.23.00-UTC` .
* **Путь к Dockerfile** можно использовать для настройки рецепта ваших образов.
  * Мы рекомендуем пока оставить значение по умолчанию; позже вы сможете прочитать об этом подробнее в разделе [#customize-server-image](#customize-server-image "mention").
* **Необязательные параметры сборки docker** можно использовать, чтобы дополнительно указать Docker более тонкие нюансы.
  * Мы рекомендуем пока оставить значение по умолчанию, вы можете [прочитать подробнее позже в документации Docker](https://docs.docker.com/reference/cli/docker/image/build/#options).

☑️ Когда вас устроит конфигурация, нажмите **Контейнеризировать с Docker**, дождитесь завершения процесса и убедитесь, что в консоли Unity нет новых ошибок. Выполнение этого шага приведёт к тому, что **в вашей локальной машине появляется новый образ**. Вы можете проверить это либо в Docker Desktop на вкладке Images под Local (по умолчанию), либо в CLI Docker, выполнив `docker images` .

✅ Теперь можно перейти к следующему шагу.

<details>

<summary>Устранение неполадок и FAQ</summary>

`/bin/bash: docker: command not found` , или `не удалось найти Packages\com.edgegap.unity-servers-plugin\Editor`

* Сначала убедитесь, что вы завершили [Инструменты разработчика](/ru/unity/developer-tools.md#usage-requirements).
* Подтвердите, что вы верифицировали свой аккаунт Edgegap; вы должны были получить ссылку для подтверждения по электронной почте.
* После обновления Docker Desktop некоторые настройки могли сброситься. Попробуйте перейти в Docker Desktop Settings / Advanced и для «Choose how to configure the installation of Docker’s CLI tools:» выбрать «System (requires password)».

***

`docker build требует ровно 1 аргумент`

* Пожалуйста, проверьте, что ваш тег образа не содержит пробельных символов (пробелов, табуляций). Повторный ввод значения тега образа поможет убедиться, что вы случайно не скопировали такие символы.

***

`(HTTP code 400) unexpected - invalid tag format`

* Это [известная проблема с версией Docker для macOS 4.33](https://github.com/docker/for-win/issues/14258), пожалуйста, рассмотрите откат до 4.32 или обновление до 4.35.

***

`ERROR: failed to solve: ubuntu:22.04: failed to resolve source metadata for http://docker.io/library/ubuntu:22.04: failed to authorize: failed to fetch oauth token`

* Вы находитесь в Китае? Ваше соединение может прерываться Великим файрволом. Попробуйте вручную выполнить `docker pull ubuntu:22.04` в командной строке (откройте командную строку, нажав Win+R, затем введите `cmd` и нажмите Enter).

***

`System.IndexOutOfRangeException: Index was outside the bounds of the array.`

* Если вы установили наш плагин Unity quickstart, загрузив ZIP, кэш Unity Editor может быть повреждён. Попробуйте удалить копию плагина и установить его через git URL или из Unity Asset Store. Пакет Newtonsoft.JSON больше не должен быть нужен, так как он автоматически включается вместе с другими исходниками.

***

Размер моего docker-образа огромный (более 1 ГБ) / крошечный (меньше 100 МБ), это нормально?

* В некоторых случаях это может быть нормально, если вы можете запустить сервер и успешно подключиться (см. [#id-4.-test-your-server-locally](#id-4.-test-your-server-locally "mention")). Если это не так, рассмотрите возможность пересмотра параметров сборки, сброса их к значениям по умолчанию и постепенного добавления опций, чтобы увидеть, как они влияют на размер сборки. Также см. [#optimize-server-build-size](#optimize-server-build-size "mention").

***

У меня возникает другая проблема, не упомянутая нигде в этой документации.

* Сначала, пожалуйста, попробуйте [обновить ваш плагин Edgegap](https://github.com/edgegap/edgegap-unity-plugin?tab=readme-ov-file#update-the-plugin-in-unity) — возможно, мы выпустили исправление. Если это не поможет, пожалуйста, свяжитесь с нами в нашем [Discord-сообществе](https://discord.gg/NgCnkHbsGp) и мы оперативно разберёмся вместе с вами.

</details>

## 🧪 4. Тестировать сервер локально

☑️ Вы можете настроить следующие параметры (или оставить значения по умолчанию):

* **Тег образа сервера** из предыдущего шага.
  * По умолчанию используется последний тег, который вы собрали с помощью плагина.
* **Необязательные параметры docker run** можно указать для публикации нескольких портов или запуска вашего образа на машинах macOS.
  * При необходимости вы можете опубликовать несколько портов для своего контейнера — просто добавьте параметр `-p {internal port}/{protocol}` для каждого, например `-p 8080/tcp -p 7777/udp` чтобы опубликовать и сопоставить порт вашего сервера `8080` с случайным внешним портом для TCP-подключения и порт сервера `7777` со случайным внешним портом для UDP-подключения одновременно.
  * **Найдите конфигурацию порта сервера в настройках Transport или специфичных для netcode.**
  * Если вы используете машину с архитектурой ARM (macOS M1, M2, M3 и т. д.), вы должны увидеть этот необязательный параметр, включённый в ваши Необязательные параметры сборки docker: `--platform=linux/amd64` .

☑️ Когда вас устроит конфигурация, нажмите **Развернуть локальный контейнер**, дождитесь завершения процесса и убедитесь, что в консоли Unity нет новых ошибок. Выполнение этого шага приведёт к тому, что **будет запущен новый контейнер** на вашей машине разработки.

{% hint style="info" %}
Для подробностей см. Docker Desktop / Containers или команду Docker CLI `docker ps` .
{% endhint %}

☑️ Теперь пора **подключить игровой клиент Unity Editor к вашему локальному docker-контейнеру** чтобы убедиться, что образ вашего сервера работает корректно. Найдите настройки клиента netcode и укажите:

* `localhost` или `0.0.0.0` (в большинстве случаев эквивалентно) вместо IP сервера,
* случайное значение внешнего порта, найденное в Docker Desktop / Containers / edgegap-server-test.

✅ Теперь можно перейти к следующему шагу.

<details>

<summary>Устранение неполадок и FAQ</summary>

Мне не удаётся подключиться к локальному docker-контейнеру с помощью игрового клиента Unity Editor.

* Сначала убедитесь, что статус контейнера Up и что он не Restarting и не Exited, что указывало бы на исключение во время выполнения. Если контейнер не запущен, посмотрите его логи через вкладку Docker Desktop Containers (нажмите на контейнер) или используя `docker logs {container_id} --timestamps` через docker CLI.
* Затем проверьте, что настройка порта Network Manager из вашей сборки сервера совпадает с опубликованным портом в **Необязательные параметры docker run**. Если нет, попробуйте сбросить или вручную изменить значение этого поля ввода, чтобы оно совпадало с `{container}` портом в настройке Network Manager. Найдите ваш протокол в настройках netcode.
* Наконец, убедитесь, что настройки netcode игрового клиента Unity Editor используют порт, опубликованный в **Необязательные параметры docker run** (см. скриншот выше).

***

`(Segmentation fault) - core dumped`

* Если вы используете машину с архитектурой ARM (macOS M1, M2, M3 и т. д.), вы должны увидеть этот необязательный параметр, включённый в ваши Необязательные параметры сборки docker: `--platform=linux/amd64` . Если нет, попробуйте сбросить значение этого поля ввода.

***

`SceneId of 9120233082191360994 not found in SceneObjects.`

* Это может означать, что сцена, которую вы пытаетесь загрузить, не была корректно включена в сборку — известная проблема в старых версиях плагина. Чтобы исправить это, попробуйте обновить версию интеграции netcode или [обновить ваш плагин Edgegap](https://github.com/edgegap/edgegap-unity-plugin?tab=readme-ov-file#update-the-plugin-in-unity).

***

`http2: server: error reading preface from client //./pipe/docker_engine: file has already been closed`

* Это [известная проблема в старых версиях Docker Desktop для Windows](https://github.com/docker/for-win/issues/13611). Пожалуйста, обновите приложение Docker Desktop и попробуйте контейнеризацию снова.

***

`Curl error 35: Cert handshake failed. Fatal error. UnityTls error code: 7`

* Эта ошибка указывает на проблему с проверкой корневого SSL-сертификата — известную проблему в старых версиях плагина. Чтобы исправить это, попробуйте [обновить ваш плагин Edgegap](https://github.com/edgegap/edgegap-unity-plugin?tab=readme-ov-file#update-the-plugin-in-unity).

</details>

## ☁️ 5. Загрузить в Edgegap

☑️ Вы можете настроить следующие параметры (или оставить значения по умолчанию):

* **Имя приложения** в Edgegap может совпадать с именем вашего образа или быть настроено индивидуально.
  * Пока мы выбрали копирование имени вашего образа.
* **Версия приложения** в Edgegap может совпадать с вашим тегом или быть настроена индивидуально.
  * Для названий версий приложения отлично подходят метки времени, например `2024.01.30-16.50.20-UTC` .
  * Несколько версий приложения могут указывать на один и тот же тег образа, например `v1.1.0` и `dev` .
  * Узнайте больше о [Приложения и версии](/ru/learn/orkestraciya/application-and-versions.md) позже.
* **Имя образа сервера** из шага [#id-3.-containerize-your-game-server](#id-3.-containerize-your-game-server "mention").
* **Тег образа сервера** из шага [#id-3.-containerize-your-game-server](#id-3.-containerize-your-game-server "mention").

{% hint style="success" %}
Найдите любое имя образа и тег, хранящиеся на вашем компьютере, в **Docker Desktop / Images**.
{% endhint %}

☑️ Когда вас устроит конфигурация, нажмите **Загрузить образ и создать версию App**, дождитесь завершения процесса и убедитесь, что в консоли Unity нет новых ошибок.

☑️ Вас перенаправят в наш [Dashboard](https://app.edgegap.com/), где вы сможете настроить дополнительные параметры. Выполнение этого шага приведёт к тому, что [будет создана новая версия приложения](https://app.edgegap.com/application-management/applications/list), а ваш [артефакт сборки будет помечен тегом и загружен в Container Registry Edgegap](https://app.edgegap.com/registry-management/repositories/list).

☑️ Теперь вас попросят указать порт для новой версии приложения. Убедитесь, что значение порта сервера совпадает со значением из шага [#id-4.-test-your-server-locally](#id-4.-test-your-server-locally "mention") из настроек Transport или специфичных для netcode.

✅ Теперь можно перейти к следующему шагу.

## 🚀 6. Развернуть в облаке

☑️ Теперь мы выполним финальный тест и **подключим игровой клиент Unity Editor к вашему облачному развёртыванию**. Введите данные подключения игрового клиента из развёртывания:

* **Хост** **URL** указывающий на IP сервера, обычно в `NetworkManager` компоненте.
* **Внешний порт** сопоставляемый с [внутренним портом прослушивания сервера](/ru/learn/orkestraciya/application-and-versions.md#port-mapping), обычно в компоненте Transport.

<details>

<summary>Устранение неполадок и FAQ</summary>

Не удаётся подключить клиентов к серверу - `Превышено время ожидания запроса.` , `请求超时` , `ConnectionFailed` , или `Проверка порта не удалась`

* Сначала убедитесь, что развёртывание Ready и в логах развёртывания нет исключений во время выполнения или ошибок. Если развёртывание остановилось, смотрите логи в нашем [Dashboard](https://app.edgegap.com/deployment-management/deployments/list).
* Если вы используете netcode Mirror, вам нужно иметь ["Auto Start Server"](https://mirror-networking.gitbook.io/docs/hosting/edgegap-hosting-plugin-guide#build-and-push) выбранным в вашем `NetworkManager` , пересоберите, загрузите и повторно разверните ваш сервер.
* Если вы используете netcode FishNet, вам нужно включить [“Start on Headless”](https://fish-networking.gitbook.io/docs/manual/components/managers/server-manager#settings-are-general-settings-related-to-the-servermanager) в вашем `ServerManager`, пересоберите, загрузите и повторно разверните ваш сервер.
* Если вы используете netcode Photon Fusion 2, убедитесь, что ваш сервер передаёт публичный IP развёртывания, внешний порт и `roomCode` на сервере, и тот же код комнаты на клиенте в [“NeworkRunner.StartGame”](https://doc.photonengine.com/fusion/current/manual/network-runner#creating-or-joining-a-room) параметре `StartGameArgs`. Deployment ID (например `b63e6003b19f`) — отличный выбор, так как он глобально уникален и легко доступен клиенту через [Matchmaker](/ru/learn/podbor-matchei/matchmaker-in-depth.md) и [Подробный обзор](/ru/learn/podbor-matchei/matchmaker-in-depth.md#injected-environment-variables).
* Затем проверьте, что настройка порта в параметрах netcode вашей сборки сервера совпадает с внутренним портом в вашем [Версия приложения](https://app.edgegap.com/application-management/applications/list). Вы можете изменить сопоставление портов, отредактировав [Версия приложения](https://app.edgegap.com/application-management/applications/list) без пересборки. Найдите ваш протокол в интеграции netcode.
* Пожалуйста, убедитесь, что ваш игровой клиент подключается к **внешнему порту** указанному на странице сведений о вашем развёртывании; это значение всегда будет случайным по соображениям безопасности.
* Если вы используете протокол Secure Websocket (WSS) в своей интеграции netcode, убедитесь, что в конфигурации порта WSS включён TLS Upgrade. [Версия приложения](https://app.edgegap.com/application-management/applications/list) Порт
* Вы находитесь в Китае и используете [Smart Fleets](https://docs.edgegap.com/docs/deployment/session/fleet-manager/fleet)? Ваше соединение может быть заблокировано Великим файрволом. Рассмотрите возможность добавить сервер, расположенный в Китае, в ваш пул или использовать VPN для подключения.

***

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

* Если процесс сервера аварийно завершится из-за исключения, наша система автоматически попытается перезапустить сервер. Рассмотрите [тестирование вашего сервера локально](#id-4.-test-your-server-locally) чтобы выявить первопричину.
* Мы храним логи только на время развёртывания; если вы хотите просмотреть логи после остановки развёртывания, пожалуйста, [интегрируйте стороннее хранилище логов](https://docs.edgegap.com/docs/deployment/endpoint-storage).
* См. [/pages/4ad5d792bc82dceeaec6d7dd56165ae188da0417#id-5.-deployment-stopped](https://docs.edgegap.com/ru/pages/4ad5d792bc82dceeaec6d7dd56165ae188da0417#id-5.-deployment-stopped "mention") чтобы узнать все причины остановки вашего развёртывания.

***

Моё развёртывание автоматически остановилось через X минут.

* Развёртывания на бесплатном тарифе имеют ограничение в 60 минут; пожалуйста, рассмотрите возможность обновления аккаунта.
* Все развёртывания будут завершены через 24 часа работы в соответствии с нашей политикой очистки серверов, для обслуживания инфраструктуры и чтобы предотвратить неожиданные расходы, если развёртывание не было корректно остановлено. Для серверов с длительным временем работы рассмотрите использование [Частные флоты](/ru/learn/orkestraciya/chastnye-floty.md) с [Сохранение состояния](/ru/learn/orkestraciya/sokhranenie-sostoyaniya.md).
* См. [/pages/4ad5d792bc82dceeaec6d7dd56165ae188da0417#id-5.-deployment-stopped](https://docs.edgegap.com/ru/pages/4ad5d792bc82dceeaec6d7dd56165ae188da0417#id-5.-deployment-stopped "mention") чтобы узнать все причины остановки вашего развёртывания.

***

Моё развёртывание готово, но я не могу подключиться к нему ещё несколько минут после этого.

* После того как развёртывание становится Ready, начинается инициализация игрового движка. Этот процесс может занять от нескольких секунд до нескольких минут, и сервер не принимает подключения игроков в этот период.
* Рассмотрите возможность оптимизации инициализации сервера, чтобы сократить этот период времени.
* Игровые клиенты должны повторять попытки подключения с интервалом в 1 секунду в течение ограниченного времени (в зависимости от длительности инициализации), после чего они должны возвращаться в матчмейкинг.
* Рассмотрите возможность добавления загрузочной сцены, чтобы сервер мог выполнять инициализацию (и переход в случае Unreal Engine) одновременно с клиентами, синхронизируя состояние обоих.

***

Моё устройство Meta Quest выдаёт `HTTP 0: Cannot resolve destination host` .

* При сборке приложений Unity для целевой платформы Android разрешение на доступ в Интернет может автоматически удаляться из выходного APK-артефакта сборки клиента.
* Добавьте разрешения снова в (требуется последующая пересборка клиента):
  * Project Settings / OpenXR / :gear: Meta Quest Support / Force Remove Internet Permissions (снимите флажок).
  * Player Settings / Internet Access (установите require).

***

Что произойдёт, если игрок покинет моё развёртывание?

* По умолчанию серверы не отклоняют подключения игроков. Аутентификация игроков — задача ваших разработчиков, поскольку можно использовать разные методы и поставщиков аутентификации игроков.
* Игровые клиенты могут хранить информацию о подключении локально, чтобы попытаться переподключиться в случае неожиданного сбоя клиента.
* Чтобы позволить игрокам присоединяться к уже идущим играм, рассмотрите использование [Подробный обзор](/ru/learn/podbor-matchei/matchmaker-in-depth.md#backfill) или [Sessions](https://docs.edgegap.com/docs/deployment/session).

***

Мой сервер показывает 100% загрузки CPU после перехода в состояние ready.

* Это может не быть проблемой, поскольку игровые движки, как правило, выполняют ресурсоёмкие операции CPU во время инициализации сервера. Если загрузка CPU не снижается через 2–3 минуты после запуска развёртывания, возможно, вам нужно оптимизировать сервер или увеличить ресурсы версии приложения.
* Снижение частоты тиков может повлиять на загрузку CPU, поскольку сервер выполняет меньше операций обмена сообщениями.
* Если вы используете netcode Mirror, вам нужно иметь ["Auto Start Server"](https://mirror-networking.gitbook.io/docs/hosting/edgegap-hosting-plugin-guide#build-and-push) выбранным в вашем `NetworkManager` , пересоберите, загрузите и повторно разверните ваш сервер.
* Если вы используете netcode FishNet, вам нужно включить [“Start on Headless”](https://fish-networking.gitbook.io/docs/manual/components/managers/server-manager#settings-are-general-settings-related-to-the-servermanager) в вашем `ServerManager`, пересоберите, загрузите и повторно разверните ваш сервер.
* В бесплатном тарифе вы ограничены 1.5 vCPU и 3 ГБ памяти (RAM).
* Вы можете увеличить выделенные ресурсы при создании новой версии приложения. Вы можете дублировать свою версию приложения в нашей Dashboard и корректировать эти значения по мере необходимости, без пересборки сервера или образа.

***

Моё развёртывание постоянно перезапускается и показывает ошибку `OOM kill`

* Это вызвано превышением выделенного объёма памяти. Рассмотрите возможность оптимизации использования памяти с помощью пуллинга объектов, сжатия или удаления ненужных объектов в сцене.
* Убедитесь, что ваш проект загружает сцену по умолчанию, содержащую ваш `NetworkManager` и что сцена включена в Build Settings Unity.
* В бесплатном тарифе вы ограничены 1.5 vCPU и 3 ГБ памяти (RAM).
* Вы можете увеличить выделенные ресурсы при создании новой версии приложения. Вы можете дублировать свою версию приложения в нашей Dashboard и корректировать эти значения по мере необходимости, без пересборки сервера или образа.

***

Иногда использование памяти (RAM) моего сервера резко возрастает до высокого значения, это проблема?

* Пока вы остаётесь в пределах выделенного объёма памяти версии приложения, это не является проблемой.
* Превышение выделенного объёма памяти версии приложения приведёт к `OOM kill` (см. выше).

***

Будет ли производительность моего сервера снижаться из-за других серверов, работающих на той же машине?

* Нет, наша платформа гарантирует, что выделенные ресурсы не будут использоваться другими студиями или другими серверами на общей инфраструктуре. С Edgegap у вас нет шумных соседей.

</details>

## 👉 Следующие шаги

### Остановить развёртывания

Узнайте о различных способах [остановки развёртываний](https://docs.edgegap.com/ru/pages/4ad5d792bc82dceeaec6d7dd56165ae188da0417#id-5.-deployment-stopped) после завершения матча и ухода игроков.

Для корректного завершения работы мы настоятельно рекомендуем внедрить API самозавершения в вашей игре:

<details>

<summary>Пример фрагмента кода Unity C# self-stop API</summary>

```csharp
using System;
using System.Collections;
using UnityEngine;
using UnityEngine.Networking;

public class EdgegapSelfStop : MonoBehaviour
{
    private const int MaxRetries = 2;
    private const int TimeoutSeconds = 30;
    private string url = Environment.GetEnvironmentVariable("ARBITRIUM_DELETE_URL");
    private string token = Environment.GetEnvironmentVariable("ARBITRIUM_DELETE_TOKEN");

    public void Run()
    {
        StartCoroutine(SendDeleteWithRetry());
    }

    private IEnumerator SendDeleteWithRetry()
    {
        if (string.IsNullOrEmpty(url))
        {
            Debug.LogError("Edgegap | ARBITRIUM_DELETE_URL is not set.");
            yield break;
        }

        if (string.IsNullOrEmpty(token))
        {
            Debug.LogError("Edgegap | ARBITRIUM_DELETE_TOKEN is not set.");
            yield break;
        }

        int attempt = 0;

        while (attempt <= MaxRetries)
        {
            attempt++;

            using (UnityWebRequest request = UnityWebRequest.Delete(url))
            {
                request.timeout = TimeoutSeconds;
                request.SetRequestHeader("Authorization", token);

                yield return request.SendWebRequest();

                if (request.result == UnityWebRequest.Result.Success)
                {
                    Debug.Log("Edgegap | DELETE request succeeded.");
                    yield break;
                }

                Debug.LogWarning(
                    $"Edgegap | DELETE attempt {attempt} failed.\n" +
                    $"Result: {request.result}, Error: {request.error}"
                );

                if (attempt == MaxRetries)
                {
                    Debug.LogError("Edgegap | DELETE request failed after all retries.");
                    yield break;
                }
            }
        }
    }
}
```

</details>

{% hint style="info" %}
Ваш Unity Server будет автоматически перезапущен в случае сбоя или нехватки памяти.
{% endhint %}

### Внедрённые переменные

Читайте полезную информацию, такую как ID развёртывания, IP-адрес сервера, местоположение сервера и многое другое, получая доступ к внедрённым переменным окружения. Каждое развёртывание автоматически включает:

* [Переменные развёртывания](/ru/learn/orkestraciya/deployments.md#injected-environment-variables) - автоматически предоставляются Edgegap,
* [Переменные матчмейкинга](/ru/learn/podbor-matchei/matchmaker-in-depth.md#injected-environment-variables) - автоматически предоставляются Edgegap при использовании [Подбор матчей](/ru/learn/podbor-matchei.md),
* [Переменные версии приложения](/ru/learn/orkestraciya/application-and-versions.md#injected-variables) - настраиваемые пары ключ-значение, задаваемые вами.

**Проверьте, является ли текущий экземпляр игровым клиентом или сервером** проверив, установлена ли переменная Edgegap:

```csharp
if (
  string.IsNullOrEmpty(Environment.GetEnvironmentVariable("ARBITRIUM_REQUEST_ID"))
)
{
  // код клиента
} else {
  // код сервера
}
```

### Sessions

Запуск ваших развёртываний вручную, с подстановкой URL и портов, не подойдёт для живой игры.

{% hint style="success" %}
[**Подробнее о матчмейкинге**](/ru/learn/podbor-matchei.md) **чтобы развёртывать автоматически, как раз вовремя**, когда игроки выходят в онлайн.
{% endhint %}

### Оптимизировать сборки сервера

**Пересобирайте только те ресурсы, которые изменились с последней сборки.**

Рассмотрите использование [инкрементальных сборок Unity](https://docs.unity3d.com/Manual/incremental-build-pipeline.html) чтобы ускорить время сборки.

* Рассмотрите использование [инкрементальных сборок Unity](https://docs.unity3d.com/Manual/incremental-build-pipeline.html) чтобы ускорить время сборки.

**Включайте только то, что абсолютно необходимо для работы вашего сервера.**

* Копирование неиспользуемых файлов в ваши образы приводит к разрастанию образа, более долгой загрузке, более медленной скорости кэширования и более медленному общему запуску сервера. [Ознакомьтесь с рекомендациями по оптимизации Docker-образа](https://docs.docker.com/build-cloud/optimization/#dockerignore-files).

**Отключите статическую батчинг-обработку мешей, чтобы уменьшить размер образа.**

* [Отключите статический batching для более быстрой сборки, загрузки и развёртывания.](https://docs.unity3d.com/Manual/DrawCallBatching.html)

**Сжимайте меши, чтобы уменьшить размер образа.**

* [Установите сжатие мешей на High для более быстрой сборки, загрузки и развёртывания.](https://docs.unity3d.com/6000.0/Documentation/Manual/compressing-mesh-data-optimization.html)
* Vertex compression не влияет на размер образа.

**Реализуйте условную ленивую загрузку ресурсов.**

* Исключите ассеты только для клиента, [отключив CPU read/write для текстур и мешей](https://docs.unity3d.com/6000.0/Documentation/Manual/dedicated-server-optimizations.html).
* Рассмотрите использование [Unity Addressables](https://docs.unity3d.com/Packages/com.unity.addressables@2.1/manual/index.html) для сборок клиента, чтобы ускорить сборки и развёртывания за счёт [загрузки ресурсов как раз вовремя](https://docs.unity3d.com/Packages/com.unity.addressables@1.19/manual/LoadingAddressableAssets.html), или пропускайте загрузку некоторых ресурсов в сборках сервера, проверяя наличие [Развертывания](/ru/learn/orkestraciya/deployments.md#injected-environment-variables).

**Рассмотрите использование** [**многоэтапных Docker-сборок (ссылка)**](https://docs.docker.com/build/building/multi-stage/)**.**

* Выносите большие зависимости сервера в отдельный образ, чтобы переиспользовать их в многоэтапных сборках. Docker будет кэшировать каждый слой и просто повторно использовать предыдущую версию, пропуская загрузку этой части, если только не будет явно указано иное, что сэкономит вам трафик и время ожидания завершения загрузки.
* Если вы не уверены, почему одна из команд вашего Dockerfile выдаёт ошибку, попробуйте отладить локально. Создайте новый этап прямо перед тем, как возникает проблема (добавьте второй `FROM` командой), используйте `--target` чтобы указать процессу сборки остановиться на проблемном этапе, а затем `docker exec -it {container} /bin/bash` чтобы войти в интерактивный терминал внутри контейнера. После этого вы можете использовать команды оболочки в вашем базовом образе для дальнейшего исследования (например, `top` в Ubuntu).

### Настроить образ сервера

Мы также поддерживаем добавление собственного Dockerfile для пользователей, которым нужен больший контроль над образами из-за оптимизации размера сборки, лишних зависимостей или более сложного процесса запуска. При желании вы можете указать путь к своему пользовательскому Dockerfile на шаге [#id-3.-containerize-your-game-server](#id-3.-containerize-your-game-server "mention"). Теперь мы поделимся несколькими советами и лучшими практиками «сделай сам».

**Возникли проблемы при использовании WebSockets или HTTPS-запросов?**

* Если вы получаете `Curl error 35: Cert handshake failed. Fatal error. UnityTls error code: 7` не отчаивайтесь, это известная проблема со старыми базовыми (`FROM`) образами, включающими просроченный сертификат корневого удостоверяющего центра. Вы можете исправить это, обновившись до более новой версии базового образа (например, `ubuntu:22.04`), и выполнив `update-ca-certificates` , добавьте это в ваш Dockerfile:

  ```docker
  FROM ubuntu:22.04

  RUN apt-get install -y ca-certificates && \
      apt-get clean && \
      update-ca-certificates
  ```

{% hint style="info" %}
Уперлись в стену? Мы доступны в нашем [Discord-сообществе](https://discord.gg/MmJf8fWjnt) и будем рады помочь.
{% endhint %}


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.edgegap.com/ru/unity.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
