HIKI Tech Blog

yhikishimaのブログ。ゆるくUE4やUnity、web開発の記事を書いてます。

UE5 + Unity Game Servicesでマルチプレイ vol.1 ホスティングサーバーに接続

1. はじめに

UE5とUnity Game Service (https://unity.com/ja/unreal-engine) でマルチプレイができそうだなと思って検証してみました。

ドキュメントはこちら

Game Server Hosting SDK for Unreal Engine

2. SDK導入

UE5のソースコードDL周りは割愛します。

Unity Gaming Services

↑のセットアップ手順を進めていきます。

手順通りSDKのDL画面までいきます。

integrate game server にUnrealを選択します。

↑のLinuxもしくはWindows版をDLしてください。(ビルドが現状Linuxしか対応してないようなので、Linux版をDLして進めていきます。)

DLできたら、プロジェクトのPluginsフォルダに配置してビルドしてください。 (Pluginsがなければ作成する)

プロジェクトを開いて、プラグインの一覧に Multiplay Game Server SDK があり有効になっていればOKです。

3. SDK初期化処理追加

特にドキュメントには明記されていなかったのですが、どうも必要なようなので、サーバー側の処理に初期化処理を追加しておきます。

新しくAGameSession を継承したクラスを追加します。

AGameSessoinはこちらを参考に。

AGameSession | Unreal Engine Documentation

RegisterServer をoverrideして以下の処理を追加。

void ACPP_GameSession::RegisterServer()
{
    Super::RegisterServer();
    
    UE_LOG(LogTemp, Log, TEXT("ACPP_GameSession::RegisterServer"));

    // Setup Server
    InitMultiplayServerSystem();

    if (ServerQueryHandlerSubsystem)
    {
        if (bool bConnect = ServerQueryHandlerSubsystem->Connect())
        {
            UGameInstance* GameInstance = GetWorld()->GetGameInstance();
            UMultiplayServerConfigSubsystem * ServerConfigSubsystem = GameInstance->GetSubsystem();

            const FMultiplayServerConfig & ServerConfig = ServerConfigSubsystem->GetServerConfig();
            UE_LOG(LogTemp, Log, TEXT("Server ID: %lld Allocation ID: %s Server Query Port: %u Port: %u Server Log Directory: %s"),
                ServerConfig.ServerId,
                *ServerConfig.AllocationId,
                ServerConfig.QueryPort,
                ServerConfig.Port,
                *ServerConfig.ServerLogDirectory);
            
            ServerQueryHandlerSubsystem->SetServerName(TEXT("Multiplay Server"));
            ServerQueryHandlerSubsystem->SetGameType(TEXT("Multi"));
            ServerQueryHandlerSubsystem->SetMap(TEXT("ThirdPersonServerMap"));
            ServerQueryHandlerSubsystem->SetPort(ServerConfig.Port);
        }
        else
        {
            UE_LOG(LogTemp, Error, TEXT("ServerQueryHandlerSubsystem Connect is Failed"));
        }
    }
}

void ACPP_GameSession::InitMultiplayServerSystem()
{
    if (ServerQueryHandlerSubsystem)
    {
        return;
    }
    
    UGameInstance* GameInstance = GetWorld()->GetGameInstance();
    
    GameServerSubsystem = GameInstance->GetSubsystem();
    GameServerSubsystem->SubscribeToServerEvents();

    ServerQueryHandlerSubsystem = GameInstance->GetSubsystem();
}

上記で初期化はできているかと思いますが、プレイヤーが入ったり、出たりしたときにPlayerの人数を変更する処理を追加しておきます。


void ACPP_GameSession::PostLogin(APlayerController* NewPlayer)
{
    Super::PostLogin(NewPlayer);

    InitMultiplayServerSystem();

    if(ServerQueryHandlerSubsystem)
    {
        ServerQueryHandlerSubsystem->IncrementCurrentPlayers();
    }
}

void ACPP_GameSession::NotifyLogout(const APlayerController* PC)
{
    Super::NotifyLogout(PC);

    InitMultiplayServerSystem();

    if(ServerQueryHandlerSubsystem)
    {
        ServerQueryHandlerSubsystem->DecrementCurrentPlayers();
    }
}

上記マルチシステムのAPIはBPからも呼べるようなので、BPにしたい方はこちらから参考。

Game Server Hosting SDK for Unreal Engine

上記GameSessionを呼ぶように、AGameModeを継承したクラスを作成して、GetGameSessionClassの関数をオーバーライドする(ThirdPersonのサンプルプロジェクトであれば、すでに作成されているはずなので、そちらでオーバーライドすればよい)

TSubclassOf AMutiSampleUGSGameMode::GetGameSessionClass() const
{
    return ACPP_GameSession::StaticClass();
}

4. サーバービルドしてアップロード

次にビルドをアップロードします。

Builds

↑のページを参考に。

まず MultiplayGameServerSDK モジュールの依存関係として以下のようにUnreal プロジェクトの Build.cs ファイルに追加します。

PublicDependencyModuleNames.AddRange(new string[] { "Core", "CoreUObject", "Engine", "InputCore", "HeadMountedDisplay", "EnhancedInput", "MultiplayGameServerSDK"});

.uprojectにて Generate Visual Studio Project Files する

ビルドして起動する。

サーバー用にマップを作成して、サーバーでのデフォルトマップに設定しておきます。

プロジェクト設定から作成したマップをパッケージの際に追加されるよう、設定します。

次にLinuxにてパッケージ化します。

Linuxでのビルドする方法については以下など参考

UE5プロジェクトをLinux向けにPackageする方法

パッケージのターゲットを作成したターゲットサーバーにしてLinuxをパッケージ化します。

cookでエラーが発生するので、該当のumapを削除する。

上記ファイルを削除したら、再度Linuxをパッケージ化。

パッケージが完了したら、Unity Game Servicesのダッシュボードに戻って、 Create Build を押す。

ビルドの詳細が表示されるので、ビルド名を入力して、Linux Direct File Upload を選択する。

Linuxのパッケージビルドして、ビルドされたファイルを選択して、Uploadする

uploadが完了したらversionが表示されるので、完了。

5. ビルド設定追加

Unity Game ServicesのダッシュボードのBuild configurationsを押して、Create build configuration を押す。

Build configurations nameを入力して、Buildには先ほどアップロードしたビルド、GameServerExecutableには .sh を入力。 Query Type はそのまま SQPにして次へ。

Configuration variables は必要あれば追加。

Launch Parameter はPortを指定したいので、以下に変更。

logの場所も階層を意識する必要があるので、以下で設定。

Usage settingsDefaultのまま完了。

6. フリートの作成

Unity Game ServicesのダッシュボードのFleetsを押して、Create fleet を押す。

Fleet Name を入力して、Operating SystemLinux に選択、Build Configuration を先ほど作成したものを選択。

Region を ひとまず Asia に選択して、Min available serversを 1 、Max serversも 1 にして完了。

7. テストアロケーションの作成

Unity Game ServicesのダッシュボードのTest allocationを押して、Create a test allocation を押す。

FleetRegionBuild configuration を先ほど作成したものを選択。

Run Test を押して、Successになれば成功。

8. クライアントからサーバーに接続

Unity Game ServicesのダッシュボードのServersを押して、サーバーの一覧が表示される。一番上のサーバーを選択して、サーバーの Start Server を押す。

するとサーバーが稼働するので、サーバーのIPを確認。

UE5を起動して、プレイヤー数を2にしてプレイ。

先ほどのIPを Open commandで実行してサーバーに入れることを確認。 (ポート指定なしでも入れました。)

Analyticsでも確認。

これでホスティングサーバーに入れることを確認できました。

次回はマッチメイキング周りの設定をしていきます。

参考

Setting up Game Server Hosting (Multiplay) in Unreal Engine | Unity Gaming Services - YouTube

Game Server Hosting SDK for Unreal Engine