기술 자료

지원

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++.
읽는 시간 3분최근 업데이트: 9시간 전

다음 섹션에서는 Unreal Engine 시스템의 보조 시스템을 사용하여 Matchmaker SDK와 연동하는 방법을 설명합니다. Unity Gaming Services SDK는 두 가지 매치메이커 인터페이스를 제공합니다.

Matchmaker SDK를 종속성으로 추가

계속하기 전에 아래와 같이 모듈의 공개 종속성으로
MatchmakerSDK
를 추가한 다음, include 문으로 클래스에 플러그인 헤더 파일을 가져옵니다.
Unreal 프로젝트 빌드 파일(
YourProjectName.Build.cs
)의 모듈 종속성에
MatchmakerServer
MatchmakerClient
를 추가합니다.
PublicDependencyModuleNames.AddRange(new string[] { "Core", "CoreUObject", "Engine", "InputCore" });PublicDependencyModuleNames.AddRange(new string[] { "MatchmakerClient", "MatchmakerServer" });PublicDependencyModuleNames.AddRange(new string[] { "Json", "JsonUtilities" });
include 문으로 클래스에서 액세스하려는 플러그인 헤더 파일을 가져옵니다.
#include "MatchmakerClientSubsystem.h"#include "MatchmakerServerSubsystem.h"

Matchmaker 클라이언트 시스템의 보조 시스템

Matchmaker 클라이언트 시스템의 보조 시스템은 매치메이킹과 매치 찾기의 클라이언트 부분을 제어합니다. 여기에는 매치메이킹 티켓 생성, 삭제, 폴링이 포함됩니다.
UMatchmakerClientSubsystem
보조 시스템에 대한 레퍼런스를 확보하면 Matchmaker 클라이언트 시스템의 보조 시스템에 액세스할 수 있습니다.
UMatchmakerClientSubsystem
UGameInstance
에서 검색할 수 있는
UGameInstanceSubsystem
입니다.
UWorld* GameWorld = GetWorld();UGameInstance* GameInstance = GameWorld->GetGameInstance();UMatchmakerClientSubsystem* MatchmakerClientSubsystem = GameInstance->GetSubsystem<UMatchmakerClientSubsystem>();

CreateTicket

CreateTicket()
메서드를 사용해 클라이언트용 매치메이킹 티켓을 생성하여 매치메이킹 프로세스를 시작합니다.
이 메서드를 호출하면
Players
배열에 있는 모든 유효한 플레이어가 그룹으로 매치메이킹 대기열에 추가되고 같은 팀의 일원으로 매치에 참여합니다.
전달할 수 있는 여러 파라미터가 있지만, 필수 파라미터는 플레이어 목록(유효한 ID를 사용하는 최소 한 명의 플레이어가 있어야 함)입니다. 기타 선택적 파라미터에는 대기열 이름, Qos 결과, 플레이어용 커스텀 데이터가 포함됩니다.
// 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)}));
SDK의 응답은
FCreateTicketResponse
를 허용하는 THandler를 사용하여 처리할 수 있습니다.

GetTicketStatus

GetTicketStatus()
메서드를 사용하여 매치메이커 서비스에 대한 클라이언트의 티켓 상태를 폴링합니다.
매치메이킹 프로세스의 성공 또는 실패를 나타내는 응답을 검색할 때까지 반복적으로 폴링을 계속해야 합니다. 이를 위해 다음 예제와 같이
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()); } }));}
SDK의 응답은
FGetTicketStatusResponse
를 허용하는 THandler를 사용하여 처리할 수 있습니다.

DeleteTicket

DeleteTicket()
메서드를 사용하여 매치메이킹 티켓을 삭제하고 매치메이킹을 취소합니다. 이는 일반적으로 매치를 찾은 후(성공 여부와 상관없이) 또는 클라이언트가 더 이상 매치메이킹 프로세스를 원하지 않을 때 수행됩니다.
SDK의 응답은
FDeleteTicketResponse
를 허용하는 응답 핸들러에서 처리할 수 있습니다.
MatchmakerClientSubsystem->DeleteTicket(TicketId, Unity::Services::Core::THandler<FDeleteTicketResponse>::CreateLambda([](FDeleteTicketResponse Response){ // Your response logic here}));
SDK의 응답은
FDeleteTicketResponse
를 허용하는 THandler를 사용하여 처리할 수 있습니다.

Matchmaker 서버 시스템의 보조 시스템

Matchmaker 서버 시스템의 보조 시스템은 매치메이킹의 서버 부분을 제어합니다. 여기에는 Backfill 티켓 생성, 승인, 삭제, 업데이트가 포함됩니다. 다음 코드 스니핏에서 보여 주는 것처럼 보조 시스템을 먼저 가져온 후
UMatchmakerServerSubsystem
을 사용해야 합니다.
UWorld* GameWorld = GetWorld();UGameInstance* GameInstance = GameWorld->GetGameInstance();UMatchmakerServerSubsystem* MatchmakerServerSubsystem = GameInstance->GetSubsystem<UMatchmakerServerSubsystem>();
자세한 내용은 할당 페이로드를 참조하십시오(Multiplay 시스템의 보조 시스템을 사용하여
GetPayloadAllocation()
으로 액세스). 이는 MatchProperties를 처음 채우는 데 사용됩니다.

CreateBackfillTicket

플레이어(또는 플레이어들)가 인원이 모두 채워진 매치를 나가는 경우 새 Backfill 티켓을 생성해야 하고, 서버는 빈 슬롯을 채워야 합니다. 서버용 새 Backfill 티켓을 생성하려면
CreateBackfillTicket()
메서드를 사용합니다.
다음 코드 스니핏은 새 Backfill 티켓을 생성하는 방법을 보여 줍니다.
// 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}));
SDK의 응답은
FCreateBackfillTicketResponse
를 허용하는 THandler를 사용하여 처리할 수 있습니다.

ApproveBackfillTicket

Backfill 티켓을 생성한 후 승인하려면
ApproveBackfillTicket()
메서드를 사용합니다. Backfill 티켓을 승인하면 새 플레이어가 서버에 참여할 수 있습니다.
Backfill 티켓은 1초에 한 번 이하로 승인하는 것이 좋습니다. Unity Matchmaker는 20초 이내에 승인되지 않은 티켓을 삭제합니다. 다음 코드 스니핏은 새 Backfill 티켓을 승인하는 방법을 보여 줍니다.
MatchmakerServerSubsystem->ApproveBackfillTicket(BackfillTicketId, Unity::Services::Core::THandler<FApproveBackfillTicketResponse>::CreateLambda([this](FApproveBackfillTicketResponse ApproveResponse){ // Your response logic here}));
SDK의 응답은
FApproveBackfillTicketResponse
를 허용하는 THandler를 사용하여 처리할 수 있습니다.

DeleteBackfillTicket

매치가 전부 채워진 경우 Backfill 티켓을 삭제하고, 서버는 더 이상 새 플레이어를 받지 않아야 합니다. 또한 매치가 종료된 후 새 플레이어가 서버에 더 이상 들어오지 않도록 이 작업을 수행해야 합니다. 서버에서 Backfill을 중지하려면
DeleteBackfillTicket()
메서드를 사용합니다.
다음 코드 스니핏은 Backfill 티켓을 삭제하는 방법을 보여 줍니다.
MatchmakerServerSubsystem->DeleteBackfillTicket(BackfillTicketId, Unity::Services::Core::THandler<FDeleteBackfillTicketResponse>::CreateLambda([this](FDeleteBackfillTicketResponse DeleteResponse){ // Handle response here}));
SDK의 응답은
FDeleteBackfillTicketResponse
를 허용하는 THandler를 사용하여 처리할 수 있습니다.

UpdateBackfillTicket

서버의 현재 Backfill 티켓을 업데이트하려면
UpdateBackfillTicket()
메서드를 사용합니다.
매치메이킹 로직 외부에서 플레이어가 서버에 참여하거나 서버를 나갈 때마다 Backfill 티켓을 업데이트해야 합니다. 여기에는 파티 초대, 직접 연결, 친구 초대 등이 포함될 수 있으나 이에 국한되지는 않습니다. Backfill 티켓은 3초에 한 번 이하로 업데이트해야 하며, 승인된 Backfill 티켓에서 Backfill 티켓의 변경 사항을 감지한 경우 매치메이킹 주기가 완료되었는지 확인하기 위해 업데이트해야 합니다. Backfill 티켓을 너무 자주 업데이트하면 플레이어가 매치에 다시 Backfill되지 않을 수 있습니다. 자세한 내용은 매치메이킹 로직 샘플을 참조하십시오.
// 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}));
먼저
ApproveBackfillTicket
을 호출하고
ApproveBackfillTicket
에서 반환된
BackfillTicket
를 사용하여 수정한 후
UpdateBackfillTicket
에 전달하는 것이 좋습니다.
SDK의 응답은
FUpdateBackfillTicketResponse
를 허용하는 THandler를 사용하여 처리할 수 있습니다.

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);}));