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를 종속성으로 추가
계속하기 전에 아래와 같이 모듈의 공개 종속성으로MatchmakerSDKYourProjectName.Build.csMatchmakerServerMatchmakerClientinclude 문으로 클래스에서 액세스하려는 플러그인 헤더 파일을 가져옵니다.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 클라이언트 시스템의 보조 시스템은 매치메이킹과 매치 찾기의 클라이언트 부분을 제어합니다. 여기에는 매치메이킹 티켓 생성, 삭제, 폴링이 포함됩니다.
UMatchmakerClientSubsystemUMatchmakerClientSubsystemUGameInstanceUGameInstanceSubsystemUWorld* GameWorld = GetWorld();UGameInstance* GameInstance = GameWorld->GetGameInstance();UMatchmakerClientSubsystem* MatchmakerClientSubsystem = GameInstance->GetSubsystem<UMatchmakerClientSubsystem>();
CreateTicket
CreateTicket()PlayersSDK의 응답은// 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)}));
FCreateTicketResponseGetTicketStatus
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);
SDK의 응답은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()); } }));}
FGetTicketStatusResponseDeleteTicket
DeleteTicket()FDeleteTicketResponseSDK의 응답은MatchmakerClientSubsystem->DeleteTicket(TicketId, Unity::Services::Core::THandler<FDeleteTicketResponse>::CreateLambda([](FDeleteTicketResponse Response){ // Your response logic here}));
FDeleteTicketResponseMatchmaker 서버 시스템의 보조 시스템
Matchmaker 서버 시스템의 보조 시스템은 매치메이킹의 서버 부분을 제어합니다. 여기에는 Backfill 티켓 생성, 승인, 삭제, 업데이트가 포함됩니다. 다음 코드 스니핏에서 보여 주는 것처럼 보조 시스템을 먼저 가져온 후UMatchmakerServerSubsystemUWorld* GameWorld = GetWorld();UGameInstance* GameInstance = GameWorld->GetGameInstance();UMatchmakerServerSubsystem* MatchmakerServerSubsystem = GameInstance->GetSubsystem<UMatchmakerServerSubsystem>();
자세한 내용은 할당 페이로드를 참조하십시오(Multiplay 시스템의 보조 시스템을 사용하여
GetPayloadAllocation()CreateBackfillTicket
플레이어(또는 플레이어들)가 인원이 모두 채워진 매치를 나가는 경우 새 Backfill 티켓을 생성해야 하고, 서버는 빈 슬롯을 채워야 합니다. 서버용 새 Backfill 티켓을 생성하려면CreateBackfillTicket()SDK의 응답은// 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}));
FCreateBackfillTicketResponseApproveBackfillTicket
Backfill 티켓을 생성한 후 승인하려면ApproveBackfillTicket()SDK의 응답은MatchmakerServerSubsystem->ApproveBackfillTicket(BackfillTicketId, Unity::Services::Core::THandler<FApproveBackfillTicketResponse>::CreateLambda([this](FApproveBackfillTicketResponse ApproveResponse){ // Your response logic here}));
FApproveBackfillTicketResponseDeleteBackfillTicket
매치가 전부 채워진 경우 Backfill 티켓을 삭제하고, 서버는 더 이상 새 플레이어를 받지 않아야 합니다. 또한 매치가 종료된 후 새 플레이어가 서버에 더 이상 들어오지 않도록 이 작업을 수행해야 합니다. 서버에서 Backfill을 중지하려면DeleteBackfillTicket()SDK의 응답은MatchmakerServerSubsystem->DeleteBackfillTicket(BackfillTicketId, Unity::Services::Core::THandler<FDeleteBackfillTicketResponse>::CreateLambda([this](FDeleteBackfillTicketResponse DeleteResponse){ // Handle response here}));
FDeleteBackfillTicketResponseUpdateBackfillTicket
서버의 현재 Backfill 티켓을 업데이트하려면UpdateBackfillTicket()먼저// 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}));
ApproveBackfillTicketApproveBackfillTicketBackfillTicketUpdateBackfillTicketFUpdateBackfillTicketResponseTHandler 사용
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);}));