ドキュメント

サポート

Matchmaker for the Unreal Engine

Matchmaker overview

Matchmaker for the Unreal Engine

C++ を使用した統合

Use the Matchmaker Subsystems and API to add matchmaking functionality to your Unreal Engine game in C++.
読み終わるまでの所要時間 5 分最終更新 4日前

以下のセクションでは、Unreal Engine のサブシステムを使用して Matchmaker SDK を統合する方法を示します。 Unity Gaming Services SDK では、次の 2 つの Matchmaker インターフェースを使用できます。

Matchmaker SDK を依存関係として追加する

先に進む前に、
MatchmakerSDK
をモジュールのパブリック依存関係として追加し、以下に示すようにプラグインのヘッダーファイルをクラスに加えます。
MatchmakerServer
MatchmakerClient
をモジュールの依存関係として Unreal プロジェクトのビルドファイル (
YourProjectName.Build.cs
) に追加します。
PublicDependencyModuleNames.AddRange(new string[] { "Core", "CoreUObject", "Engine", "InputCore" });PublicDependencyModuleNames.AddRange(new string[] { "MatchmakerClient", "MatchmakerServer" });PublicDependencyModuleNames.AddRange(new string[] { "Json", "JsonUtilities" });
アクセスしたいプラグインのヘッダーファイルをクラスに加えます。
#include "MatchmakerClientSubsystem.h"#include "MatchmakerServerSubsystem.h"

Matchmaker クライアントサブシステム

Matchmaker クライアントサブシステムが、マッチメイキングとマッチ検出のクライアント部分を制御します。これには、マッチメイキングチケットの作成、削除、ポーリングが含まれています。 Matchmaker クライアントサブシステムには、
UMatchmakerClientSubsystem
サブシステムへの参照を取得することでアクセスできます。
UMatchmakerClientSubsystem
UGameInstanceSubsystem
の 1 つであり、
UGameInstance
から取得できます。
UWorld* GameWorld = GetWorld();UGameInstance* GameInstance = GameWorld->GetGameInstance();UMatchmakerClientSubsystem* MatchmakerClientSubsystem = GameInstance->GetSubsystem<UMatchmakerClientSubsystem>();

CreateTicket

CreateTicket()
メソッドを使用してクライアントのマッチメイキングチケットを作成し、マッチメイキングプロセスを開始します。
このメソッドを呼び出すと、
Players
配列内のすべての有効なプレイヤーが 1 つのグループとしてマッチメイキングキューに追加され、同じチームの一員としてマッチに参加します。
複数のパラメーターを渡すことができますが、必要なパラメーターは Players リストのみです (有効な ID を使用するプレイヤーが少なくとも 1 人いる必要があります)。その他に使用できるパラメーターとしては、Queue NameQos Results、プレイヤーのカスタムデータなどがあります。
// Create Players arrayTArray<FMatchmakerPlayer> Players;// Create player definitionFMatchmakerPlayer SamplePlayer;SamplePlayer.Id = TEXT("SamplePlayer");// Adding custom player dataTSharedPtr<FJsonObject> CustomData = MakeShared<FJsonObject>();CustomData->SetNumberField("Skill", 100);CustomData->SetStringField("PreferredMap", "Dune");SamplePlayer.CustomData = CustomData;Players.Add(SamplePlayer);// Setup Ticket OptionsFCreateTicketOptions Options;Options.QueueName = TEXT("default-queue");MatchmakerClientSubsystem->CreateTicket(Players, options, Unity::Services::Core::THandler<FCreateTicketResponse>::CreateLambda([this](FCreateTicketResponse Response){ // Your response logic here (response includes Ticket Id)}));
FCreateTicketResponse
を受け取る THandler を使用して、SDK の応答を処理できます。

GetTicketStatus

GetTicketStatus()
メソッドを使用して、Matchmaker サービスに対してクライアントのチケットステータスをポーリングします。
マッチメイキングプロセスの成功または失敗を示す応答が取得されるまで、ループ内で継続的にポーリングを実行する必要があります。 そのためには以下の例のように、
FTimerDelegate
を使用してタイマーを開始します。
// Create the Timer Delegate and set the function to callFTimerDelegate PollTicketDelegate = FTimerDelegate::CreateUObject(this, &UMyCustomClass::PollTicket, Response.TicketId);// Start the Timer that runs every 5 seconds, cache PollTicketTimerHandler to use for stopping the timer later GEngine->GameViewport->GetWorld()->GetTimerManager().SetTimer(PollTicketTimerHandle, PollTicketDelegate, 5, true);
使用するマッチポーリング関数は以下の例のようになります。
void UMyCustomClass::PollTicket(FGuid TicketId){ MatchmakerClientSubsystem->GetTicketStatus(TicketId, THandler<FGetTicketStatusResponse>::CreateLambda([this, TicketId](FGetTicketStatusResponse Response) { if (Response.bWasSuccessful) { FString TicketIdStr = *TicketId.ToString(EGuidFormats::DigitsWithHyphens).ToLower(); switch (Response.Status) { case StatusEnum::Failed: UE_LOG(LogTemp, Log, TEXT("polling for ticket has failed, response was: %s"), *Response.ErrorMessage); break; case StatusEnum::Timeout: UE_LOG(LogTemp, Log, TEXT("polling for ticket has timed out, response was: %s"), *Response.ErrorMessage); break; case StatusEnum::InProgress: UE_LOG(LogTemp, Log, TEXT("polling for ticket %s is still in progress."), *TicketId.ToString(EGuidFormats::DigitsWithHyphens).ToLower()); return; case StatusEnum::Found: UE_LOG(LogTemp, Log, TEXT("polling for ticket has completed, match found with ip: %s"), *Response.Ip); break; default: UE_LOG(LogTemp, Log, TEXT("unknown status received for ticket: %s), *TicketId.ToString(EGuidFormats::DigitsWithHyphens).ToLower()); break; } // If we made it this far, we got a status other than InProgress so we can end the polling timer. GEngine->GameViewport->GetWorld()->GetTimerManager().ClearTimer(PollTicketTimerHandle); // Delete ticket here } else { UE_LOG(LogTemp, Log, TEXT("Failed to poll Ticket status with ticket ID: %s"), *TicketId.ToString(EGuidFormats::DigitsWithHyphens).ToLower()); } }));}
FGetTicketStatusResponse
を受け取る THandler を使用して、SDK の応答を処理できます。

DeleteTicket

マッチメイキングチケットを削除してマッチメイキングをキャンセルするには、
DeleteTicket()
メソッドを使用します。この処理を行うのは一般的に、マッチが見つかった後 (失敗した場合を含む)、またはマッチメイキングプロセスを必要とすると考えられるクライアントがなくなったときです。
FDeleteTicketResponse
を受け取る応答ハンドラーで、SDK の応答を処理できます。
MatchmakerClientSubsystem->DeleteTicket(TicketId, Unity::Services::Core::THandler<FDeleteTicketResponse>::CreateLambda([](FDeleteTicketResponse Response){ // Your response logic here}));
FDeleteTicketResponse
を受け取る THandler を使用して、SDK の応答を処理できます。

Matchmaker サーバーサブシステム

Matchmaker サーバーサブシステムが、マッチメイキングのサーバー部分を制御します。これには、バックフィルチケットの作成、承認、削除、更新が含まれています。
UMatchmakerServerSubsystem
を使用するには、以下のコードスニペットに示す方法でこれを取得する必要があります。
UWorld* GameWorld = GetWorld();UGameInstance* GameInstance = GameWorld->GetGameInstance();UMatchmakerServerSubsystem* MatchmakerServerSubsystem = GameInstance->GetSubsystem<UMatchmakerServerSubsystem>();
詳細については、割り当てペイロード を参照してください (
GetPayloadAllocation()
による Multiplay サブシステムへのアクセス)。これは、最初に MatchProperties に入力するために使用されます。

CreateBackfillTicket

1 人または複数のプレイヤーが満員のマッチから退出したときに、新しいバックフィルチケットを作成する必要があります。また、サーバーは空のスロットを埋める必要があります。サーバーに新しいバックフィルチケットを作成するには、
CreateBackfillTicket()
メソッドを使用します。
以下のコードスニペットに、新しいバックフィルチケットを作成する方法を示します。
// Setup Backfill Ticket OptionsFCreateBackfillTicketOptions CreateBackfillTicketOptions;CreateBackfillTicketOptions.Connection = TEXT("35.245.90.171:9000");CreateBackfillTicketOptions.QueueName = TEXT("default-queue");// Create Match PropertiesFMatchProperties MatchProperties;FGuid BackfillTicketId = FGuid::NewGuid();MatchProperties.BackfillTicketId = BackfillTicket.Id;MatchProperties.Region = TEXT("aaaaaaaa-1111-bbbb-2222-cccccccccccc");// Create PlayerFMatchmakerPlayer Player;Player.Id = FGuid::NewGuid().ToString();FQosResult QosResult;QosResult.Latency = 20;QosResult.PacketLoss = 5;QosResult.Region = TEXT("aaaaaaaa-1111-bbbb-2222-cccccccccccc");Player.QoSResults.Add(QosResult);MatchProperties.Players.Add(Player);// Create TeamFMatchmakerTeam Team;Team.TeamName = TEXT("Red");FGuid TeamId = FGuid::NewGuid();Team.TeamId = TeamId.ToString(EGuidFormats::DigitsWithHyphens);Team.PlayerIds.Add(Player.Id);MatchProperties.Teams.Add(Team);CreateBackfillTicketOptions.Properties.MatchProperties = MatchProperties;MatchmakerServerSubsystem->CreateBackfillTicket(CreateBackfillTicketOptions, Unity::Services::Core::THandler<FCreateBackfillTicketResponse>::CreateLambda([this, Player, Team](FCreateBackfillTicketResponse CreateResponse){ // Your response logic here}));
FCreateBackfillTicketResponse
を受け取る THandler を使用して、SDK の応答を処理できます。

ApproveBackfillTicket

作成後のバックフィルチケットを承認するには、
ApproveBackfillTicket()
メソッドを使用します。バックフィルチケットを承認することで、新しいプレイヤーがサーバーに参加できるようになります。
バックフィルチケットの承認は、最速でも 1 秒に 1 回までにすることをお勧めします。20 秒以内に承認されなかったチケットは Unity Matchmaker により削除されます。 以下のコードスニペットに、新しいバックフィルチケットを承認する方法を示します。
MatchmakerServerSubsystem->ApproveBackfillTicket(BackfillTicketId, Unity::Services::Core::THandler<FApproveBackfillTicketResponse>::CreateLambda([this](FApproveBackfillTicketResponse ApproveResponse){ // Your response logic here}));
FApproveBackfillTicketResponse
を受け取る THandler を使用して、SDK の応答を処理できます。

DeleteBackfillTicket

マッチが満員になり、サーバーで新しいプレイヤーを受け付ける必要がなくなった時点で、バックフィルチケットを削除します。マッチが終了し、サーバーに新しいプレイヤーを受け入れたくなくなった後も、同じ処理を行う必要があります。サーバーへのバックフィルを停止するには、
DeleteBackfillTicket()
メソッドを使用します。
以下のコードスニペットに、バックフィルチケットを削除する方法を示します。
MatchmakerServerSubsystem->DeleteBackfillTicket(BackfillTicketId, Unity::Services::Core::THandler<FDeleteBackfillTicketResponse>::CreateLambda([this](FDeleteBackfillTicketResponse DeleteResponse){ // Handle response here}));
FDeleteBackfillTicketResponse
を受け取る THandler を使用して、SDK の応答を処理できます。

UpdateBackfillTicket

サーバーの現在のバックフィルチケットを更新するには、
UpdateBackfillTicket()
を使用します。
プレイヤーがサーバーを抜けたとき、またはプレイヤーが対戦相手探しのロジックの外部からサーバーに参加したときには、必ずバックフィルチケットを更新してください。これにはパーティの招待、直接接続、友人の招待などが該当しますが、それに限りません。 バックフィルチケットの更新頻度が 3 秒に 1 回を超えないようにします。また、承認済みのバックフィルチケットがそのバックフィルチケットの変更を認識した後に更新することで、マッチメイキングサイクルを確実に経過させる必要があります。バックフィルチケットの更新頻度が高すぎると、バックフィルによるマッチへのプレイヤー参加がまったくできなくなる可能性があります。詳細は、対戦相手探しのロジックのサンプル を参照してください。
// From ApproveFBackfillTicket BackfillTicket;FGuid BackfillTicketId = FGuid::Parse(ApproveResponse.BackfillTicket.Id, BackfillTicketId);FBackfillTicket BackfillTicket = ApproveResponse.BackfillTicket;// Setup MatchPropertiesFMatchProperties MatchProperties;MatchProperties.BackfillTicketId = BackfillTicket.Id; // Could be retrieved in Payload allocation's MatchPropertiesMatchProperties.Region = TEXT("aaaaaaaa-1111-bbbb-2222-cccccccccccc"); // Could be retrieved in Payload allocation's MatchProperties// Add a new player to the backfill ticketFMatchmakerPlayer NewPlayer;NewPlayer.Id = TEXT("NewPlayer");TSharedPtr<FJsonObject> CustomData = MakeShared<FJsonObject>();CustomData->SetNumberField("Skill", 100);CustomData->SetStringField("PreferredMap", "Dune");NewPlayer.CustomData = CustomData;BackfillTicket.Properties.Players.Add(NewPlayer);BackfillTicket.Properties.[0].PlayerIds.Add(NewPlayer.Id);// Remove a Player from the backfill ticketFString PlayerIdToRemove = TEXT("SamplePlayer");for (FMatchmakerPlayer Player : BackfillTicket.Properties.Players){ if (Player.Id == PlayerIdToRemove) { BackfillTicket.Properties.Players.Remove(Player); break; }}if (BackfillTicket.Properties.Teams[0].PlayerIds.Contains(PlayerIdToRemove)){ BackfillTicket.Properties.Teams[0].PlayerIds.Remove(PlayerIdToRemove);}// Call to update backfill ticketMatchmakerServerSubsystem->UpdateBackfillTicket(BackfillTicketId, BackfillTicket, Unity::Services::Core::THandler<FUpdateBackfillTicketResponse>::CreateLambda([this, BackfillTicketId](FUpdateBackfillTicketResponse UpdateResponse){ // Handle Response here}));
Unity では、先に
ApproveBackfillTicket
を呼び出し、
ApproveBackfillTicket
から返された
BackfillTicket
を使用することで、
UpdateBackfillTicket
を変更して渡すことをお勧めします。
FUpdateBackfillTicketResponse
を受け取る THandler を使用して、SDK の応答を処理できます。

THandler の使用

この SDK には、ブループリントに対応するカスタムデリゲートが含まれます。THandler の使用方法は、通常の Unreal Engine デリゲートと似ています。 以下のコードスニペットに、インライン応答を使用して呼び出しを行う方法を示します。
Matchmaker::THandler<FCreateTicketResponse>::CreateLambda([ResponseDelegate](FCreateTicketResponse Response){ if (Response.bWasSuccessful) { UE_LOG(LogMatchmakerSDK, Log, TEXT("Successfully retrieved Ticket ID: %s"), *Response.TicketId); } else { UE_LOG(LogMatchmakerSDK, Error, TEXT("Failed to retrieve Ticket ID: %s"), *Response.ErrorMessage); } ResponseDelegate.ExecuteIfBound(Response);}));