# Photon Fusion 2

Узнайте, как размещать проекты Unity на Edgegap, используя техники из [Fusion 2 Asteroids Sample](https://doc.photonengine.com/fusion/current/game-samples/fusion-asteroids).

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

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

Перед началом вам потребуется:

* Unity 6 - [скачать через Unity Hub](https://unity.com/releases/unity-6),
* Проект Fusion 2 Asteroids Sample (модифицирован для Edgegap) - [скачать с GitHub](https://github.com/edgegap/netcode-sample-photon-fusion-2).

## ⚡ Развернуть и подключиться

### 1. Разверните сервер на Edgegap

☑️ Чтобы начать, вам нужно [создать бесплатную учетную запись на Edgegap](https://app.edgegap.com/auth/register). Кредитная карта не требуется.

☑️ [Создайте новую версию приложения для вашего приложения](https://app.edgegap.com/application-management/applications/fusion-2-asteroids-sample/versions/create), выберите Fusion 2 Asteroids Sample.

☑️ Откройте ваш новый проект в Unity.

☑️ Перейдите в Tools / Edgegap Hosting, затем к шагу 6. Разверните сервер на Edgegap.

☑️ Нажмите Deploy to cloud и [откройте детали вашего нового развертывания](https://app.edgegap.com/deployment-management/deployments/list).

☑️ Найдите уникальные одноразовые данные для подключения к развертыванию:

* **Host URL** в формате `780aa4260e83.pr.edgegap.net` .

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

### 2. Подключение из редактора

☑️ Откройте ваш новый проект в Unity.

☑️ Нажмите кнопку ▶️ Play, чтобы запустить клиент игры.

☑️ Введите Host URL (данные подключения из предыдущего шага) в качестве имени комнаты.

☑️ Нажмите кнопку Start Edgegap, чтобы подключиться к вашему серверу.

☑️ Подключите второго виртуального игрока с помощью [Multiplayer Play Mode](https://docs-multiplayer.unity3d.com/mppm/current/about/) или [ParrelSync](https://github.com/VeriorPies/ParrelSync).

🙌 Поздравляем с вашим первым развертыванием на Edgegap!

## ✏️ Настройка сборки сервера

{% hint style="success" %}
См. [unity](https://docs.edgegap.com/ru/unity "mention") для Unity чтобы **узнать, как собирать и настраивать серверы**.
{% endhint %}

### Создание приложения в Photon

{% hint style="info" %}
Чтобы упростить первоначальную демонстрацию, мы использовали бесплатный уровень Photon Cloud, принадлежащий Edgegap.
{% endhint %}

☑️ [Создайте бесплатную учетную запись в Photon](https://dashboard.photonengine.com/).

☑️ [Создайте приложение в Photon](https://dashboard.photonengine.com/app/create):

* `Многопользовательская игра`,
* `Fusion` Photon SDK,
* `Fusion 2` версия SDK.

☑️ Найдите ваш Application ID в формате `85314a99-56fc-4ab3-ba26-50efca09f303` .

☑️ Введите ваш ID в настройках Photon в Tools / Fusion / Fusion Hub (Alt + F).

### Интеграция проекта Fusion 2 с Edgegap

{% hint style="success" %}
См. `EdgegapServerManager.cs`  скрипт для примерной интеграции Fusion 2 с Edgegap.
{% endhint %}

{% hint style="warning" %}
Ваш `NetworkProjectConfig`  **должен использовать `Peer Mode = Single` (Выделенный сервер)**, не `Multiple` (Client-Host)!
{% endhint %}

Клиенты игры будут подключаться к игровым серверам через [Photon Fusion 2 ](https://doc.photonengine.com/fusion/current/manual/connection-and-matchmaking/matchmaking#creating-and-joining-a-game-session)[Session (комната) ](https://doc.photonengine.com/fusion/current/manual/connection-and-matchmaking/matchmaking#creating-and-joining-a-game-session)[функция](https://doc.photonengine.com/fusion/current/manual/connection-and-matchmaking/matchmaking#creating-and-joining-a-game-session).

Ваш игровой сервер должен зарегистрировать свой IP-адрес и внешний порт с именем сессии при вызове `_runnerInstance.StartGame(StartGameArgs args)`:

* используйте `GameMode.Server`  чтобы гарантировать, что ваше соединение не будет ретранслироваться через Photon Cloud (увеличивает задержку),
* используйте `NetAddress.CreateFromIpPort` метод из Fusion,
* укажите IP-адрес сервера:\
  `Environment.GetEnvironmentVariable("ARBITRIUM_PUBLIC_IP")`
* укажите внешний порт сервера:\
  `Environment.GetEnvironmentVariable("ARBITRIUM_PORT_GAMEPORT_EXTERNAL")`
  * это имя сопоставления портов по умолчанию, если вы используете наш [плагин Unity для упаковки вашего сервера](https://docs.edgegap.com/ru/unity).

Используйте Deployment Host URL Edgegap в качестве имени сессии:

* в игровом сервере получите его с помощью\
  `$"{Environment.GetEnvironmentVariable("ARBITRIUM_REQUEST_ID")}.pr.edgegap.net"`
* при тестировании игрового клиента получите его с панели управления - страница деталей развертывания / Host URL
  * создавайте развертывания для тестирования с нашего [quickstart hosting plugin](https://docs.edgegap.com/ru/unity/developer-tools#dedicated-servers-quickstart-plugin),
* в живой игре клиент получает его из [matchmaking / назначение билета / fqdn](https://docs.edgegap.com/ru/learn/podbor-igrokov/matchmaker-in-depth#player-api):
  * см. также [начало работы с Matchmaking](https://docs.edgegap.com/ru/learn/podbor-igrokov).

{% tabs %}
{% tab title="Интеграция клиента" %}
{% code title="EdgegapClientManager.cs" %}

```csharp
// получить network runner fusion 2
_runnerInstance = FindFirstObjectByType<NetworkRunner>();
_runnerInstance.ProvideInput = true;

// получить это значение из назначения Edgegap Matchmaker или Sessions API Fusion 2
string sessionName = "<requestId.pr.edgegap.net>";

// найти сессию fusion 2 (используя имя сессии)
var result = await _runnerInstance.StartGame(
    new StartGameArgs() {
        GameMode = GameMode.Client,
        SessionName = sessionName,
        ObjectProvider = _runnerInstance.GetComponent<NetworkObjectPoolDefault>(),
    }
);

// fusion теперь получит IP и порт сервера по имени сессии и подключится
```

{% endcode %}
{% endtab %}

{% tab title="Интеграция сервера" %}
{% code title="EdgegapServerManager.cs" %}

```csharp
// прочитать переменные окружения, внедренные Edgegap
string requestId = Environment.GetEnvironmentVariable("ARBITRIUM_REQUEST_ID");
string listenPort = Environment.GetEnvironmentVariable("ARBITRIUM_PORT_GAMEPORT_INTERNAL");
string connectIP = Environment.GetEnvironmentVariable("ARBITRIUM_PUBLIC_IP");
string connectPort = Environment.GetEnvironmentVariable("ARBITRIUM_PORT_GAMEPORT_EXTERNAL");

// получить network runner fusion 2
_runnerInstance = FindFirstObjectByType<NetworkRunner>();
_runnerInstance.ProvideInput = true;

// зарегистрировать сессию fusion 2, чтобы клиенты могли найти её позже (используя имя сессии)
var result = await _runnerInstance.StartGame(
    new StartGameArgs() {
        GameMode = GameMode.Server,
        SessionName = $"{requestId}.pr.edgegap.net",
        ObjectProvider = _runnerInstance.GetComponent<NetworkObjectPoolDefault>(),
        Address = NetAddress.Any(listenPort),
        CustomPublicAddress = NetAddress.CreateFromIpPort(connectIP, connectPort),
    }
);

// загрузить начальную сцену
if (result.Ok && _runnerInstance.IsServer) {
    await _runnerInstance.LoadScene(sceneName);
}
```

{% endcode %}
{% endtab %}
{% endtabs %}

### Устранение неполадок

<details>

<summary><code>Игра не существует (32758)</code></summary>

* Photon комнаты требуют, чтобы игрок подключался к региону Photon Cloud, где расположено развертывание. Развертывание из панели управления использует случайный IP игрока.
* Вам может понадобиться найти расположение развертывания на карте и настроить ваш игровой клиент в Assets / Photon / Fusion / Resources / PhotonAppSettings.asset с соответствующим [регион Photon Cloud](https://doc.photonengine.com/fusion/current/manual/connection-and-matchmaking/regions#photon-cloud-for-gaming).
* Edgegap [развертывает как можно ближе к игроку](https://docs.edgegap.com/ru/learn/orkestraciya/deployments#id-1.-server-score-strategy-best-practice) при использовании наших [плагинов](https://docs.edgegap.com/ru/unity/developer-tools) или [API](https://docs.edgegap.com/ru/docs/api/vydelennye-servery) так что в продакшене настройка региона Photon Cloud не требуется.

</details>
