매치 메이킹 SDK 빠른 시작
이 빠른 시작 가이드는 PlayFab Multiplayer SDK를 사용하여 게임에 매치 메이킹을 추가하는 전체 프로세스를 안내합니다.
이 자습서는 게임을 찾기 위해 특정 대기 목록에 티켓을 제출하는 방법을 보여줍니다. 대기 목록은 한 게임 모드 또는 여러 게임 모드에 매핑될 수 있습니다(예: 플래그 모드와 킹 오브 더 힐 모드를 같은 대기 목록에서 캡처).
매치 메이킹 서비스는 대기 목록에 있는 티켓 중에서 매치 찾기를 처리합니다. 매치가 발견되면 타이틀은 게임 플레이를 위해 플레이어를 함께 연결하는 기능을 처리해야 합니다.
참고 항목
PlayFab Multiplayer SDK는 PlayFab 로비용 API도 제공합니다.
- C++ API에 대한 자세한 내용은 Lobby SDK 빠른 시작을 참조하세요.
- Unity API에 대한 자세한 내용은 Unity 빠른 시작을 참조하세요.
- Unreal API에 대한 자세한 내용은 Unreal용 빠른 시작을 참조하세요.
필수 구성 요소
PlayFab 매치 메이킹을 사용하려면 PlayFab 계정이 필요합니다. 계정을 만드는 방법은 빠른 시작: 게임 관리자를 참조하세요.
게임 관리자에서 매치 메이킹 큐 구성
라이브러리는 게임 관리자에서 구성된 큐에 대한 티켓을 생성하는 사용자를 함께 연결합니다. 설정하는 방법에 대한 자세한 내용은 매치 메이킹 큐 구성을 참조 하세요.
PlayFab 멀티 플레이어 SDK 다운로드 및 설정
플랫폼용 C/C++ SDK를 다운로드하고 제공자 헤더와 라이브러리 파일을 빌드에 통합합니다.
참고 항목
이 빠른 시작은 C/C++ SDK 사용에 중점을 둡니다. Unity 및 Unreal 인터페이스에 대해서는 다음 문서를 참조하세요.
PlayFab 엔터티에 로그인
PlayFab Lobby SDK를 사용하려면 PlayFab 엔터티 키 및 엔터티 토큰을 사용하여 클라이언트를 인증해야 합니다. LoginWithCustomId REST API로 로그인하여 PlayFab 엔터티 키와 토큰 쌍을 획득합니다. 이 API는 PlayFab REST SDK를 통해 C/C++ 프로젝션으로도 사용할 수 있습니다.
참고 항목
LoginWithCustomId는 PlayFab 기능을 시작하는 빠른 방법이지만 함께 제공되는 로그인 메커니즘은 아닙니다. 로그인 지침은 로그인 기본 사항 및 모범 사례를 참조하세요.
PlayFab 멀티 플레이어 SDK 초기화
다음 기본 단계에 따라 PlayFab Multiplayer SDK를 초기화합니다.
- PFMultiplayerInitialize를 호출하여 SDK를 초기화합니다.
- PFMultiplayerSetEntityToken을 호출하여 플레이어 대신 라이브러리에서 사용하는 엔터티 키와 토큰을 설정합니다.
static PFMultiplayerHandle g_pfmHandle = nullptr;
...
...
HRESULT hr = S_OK;
// Initialize the PFMultiplayer library.
hr = PFMultiplayerInitialize(titleId, &g_pfmHandle);
if (FAILED(hr))
{
// handle initialize failure
}
// Set an entity token for a local user. The token is used to authenticate PlayFab operations on behalf of this user.
// Tokens can expire, and this API token should be called again when this token is refreshed.
hr = PFMultiplayerSetEntityToken(g_pfmHandle, localUserEntity, entityToken);
if (FAILED(hr))
{
// handle set entity token failure
}
매치 메이킹 티켓 만들기
PFMultiplayerCreateMatchmakingTicket을 사용하여 매치 메이킹 티켓을 생성합니다. 여기에서 매치에 포함되어야 하는 모든 로컬 사용자 및 해당 사용자와 연결하려는 모든 속성을 지정합니다.
이 함수는 또한 PFMatchmakingTicketConfiguration을 사용하여 티켓이 있는 큐, 티켓에 대한 제한 시간 및 이 티켓에 일치시키려는 모든 원격 사용자를 지정합니다.
단일 로컬 사용자와의 매치 메이킹
PFMultiplayerCreateMatchmakingTicket을 호출하여 단일 로컬 사용자에 대한 매치 메이킹을 시작할 수 있습니다.
const char* yourQueueName = ...; // This is the name of the queue you configured in Game Manager.
PFMatchmakingTicketConfiguration configuration{};
configuration.timeoutInSeconds = 120;
configuration.queueName = yourQueueName;
const char* attributes = "\"{\"color\":\"blue\", \"role\":\"tank\"}\"";
const PFMatchmakingTicket* ticket;
HRESULT hr = PFMultiplayerCreateMatchmakingTicket(
g_pfmHandle,
1, // number of local users
localUserEntity,
&attributes,
&configuration,
nullptr, // optional asyncContext
&ticket);
RETURN_IF_FAILED(hr);
원격 사용자 그룹과의 매치 메이킹
원격 사용자와 그룹 매치 메이킹을 시작하려면 한 클라이언트를 리더로 생각하는 것이 좋습니다. 리더가 PFMultiplayerCreateMatchmakingTicket을 사용하여 티켓을 만들고 configuration 매개 변수를 통해 그룹의 다른 사용자를 지정하도록 합니다. 티켓이 생성되면 GetTicketId를 호출하여 티켓 ID를 가져옵니다. 네트워킹 메시 또는 공유 PlayFab 로비와 같은 외부 메커니즘을 통해 이 ID를 서로 다른 사용자에게 보내고 각 클라이언트가 티켓 ID로 PFMultiplayerJoinMatchmakingTicketFromId를 호출하여 매치 메이킹 티켓에 참여하도록 합니다. 지정된 플레이어가 참가하기를 기다리는 동안 티켓 상태는 PFMatchmakingTicketStatus::WaitingForPlayers이고 모든 플레이어가 티켓에 참가하면 PFMatchmakingTicketStatus::WaitingForMatch로 변경됩니다.
// Creating the ticket on the leader's client
const char* remoteMemberEntityId1 = ...;
const char* remoteMemberEntityId2 = ...;
std::vector<PFEntityKey> remoteMatchMemberEntityKeys;
remoteMatchMemberEntityKeys.push_back({ remoteMemberEntityId1, "title_player_account" });
remoteMatchMemberEntityKeys.push_back({ remoteMemberEntityId2, "title_player_account" });
const char* yourQueueName = ...; // This is the name of the queue you configured in Game Manager.
PFMatchmakingTicketConfiguration configuration{};
configuration.timeoutInSeconds = 120;
configuration.queueName = yourQueueName;
configuration.membersToMatchWithCount = 2; // number of remote members to match with
configuration.membersToMatchWith = remoteMatchMemberEntityKeys.data();
const char* attributes = "\"{\"color\":\"blue\", \"role\":\"tank\"}\"";
const PFMatchmakingTicket* ticket;
HRESULT hr = PFMultiplayerCreateMatchmakingTicket(
g_pfmHandle,
1, // number of local users
localUserEntity,
&attributes,
&configuration,
nullptr, // optional asyncContext
&ticket);
RETURN_IF_FAILED(hr);
// Getting the ticket ID
PCSTR ticketId;
hr = PFMatchmakingTicketGetTicketId(ticket, &ticketId);
RETURN_IF_FAILED(hr);
// Joining the ticket on the other players' clients
const char* attributes = "\"{\"color\":\"blue\", \"role\":\"healer\"}\"";
const char* yourQueueName = ...; // This is the name of the queue you configured in Game Manager.
const PFMatchmakingTicket* ticket;
HRESULT hr = PFMultiplayerJoinMatchmakingTicketFromId(
g_pfmHandle,
1, // number of local users
localUserEntity,
&attributes,
ticketId,
yourQueueName,
nullptr, // optional asyncContext
&ticket);
여러 로컬 사용자와의 매치 메이킹
여러 로컬 사용자와 매치 메이킹할 때 하나의 PFEntityKey를 PFMultiplayerCreateMatchmakingTicket 또는 PFMultiplayerJoinMatchmakingTicketFromId 함수에 전달하는 대신 키 목록을 전달해야 합니다. 마찬가지로 각 사용자에 대한 속성 목록을 전달해야 합니다. 각 목록 항목 위치는 서로 일치해야 합니다. 속성 목록의 첫 번째 항목은 PFEntityKey 목록의 첫 번째 플레이어에 대한 속성이어야 함을 의미합니다.
const char* yourQueueName = ...; // This is the name of the queue you configured in Game Manager.
PFMatchmakingTicketConfiguration configuration{};
configuration.timeoutInSeconds = 120;
configuration.queueName = queueName;
std::vector<PFEntityKey> localMatchMemberEntityKeys{ ... };
std::vector<PCSTR> localMatchMemberAttributes{ ... };
const PFMatchmakingTicket* ticket;
HRESULT hr = PFMultiplayerCreateMatchmakingTicket(
g_pfmHandle,
static_cast<uint32_t>(localMatchMemberEntityKeys.size())
localMatchMemberEntityKeys.data(),
localMatchMemberAttributes.data(),
&configuration,
nullptr, // optional asyncContext
&ticket);
RETURN_IF_FAILED(hr);
매치 메이킹 티켓의 상태 확인
PFMultiplayerStartProcessingMatchmakingStateChanges를 호출하여 상태 변경을 수신한 다음 이러한 상태 변경 처리를 완료하면 PFMultiplayerFinishProcessingMatchmakingStateChanges를 호출하여 티켓 업데이트를 확인해야 합니다.
SDK는 티켓 상태가 변경될 때마다 TicketStatusChanged 상태 변경을 반환하고 매치 메이킹이 완료되면 TicketCompleted 상태 변경을 반환합니다.
매치 메이킹 클라이언트 SDK를 사용하는 예
HRESULT hrTicketError = S_OK;
uint32_t stateChangeCount;
const PFMatchmakingStateChange * const * stateChanges;
hr = PFMultiplayerStartProcessingMatchmakingStateChanges(g_pfmHandle, &stateChangeCount, &stateChanges);
RETURN_IF_FAILED(hr);
for (uint32_t i = 0; i < stateChangeCount; ++i)
{
const PFMatchmakingStateChange& stateChange = *stateChanges[i];
switch (stateChange.stateChangeType)
{
case PFMatchmakingStateChangeType::TicketStatusChanged:
{
const auto& ticketStatusChanged = static_cast<const PFMatchmakingTicketStatusChangedStateChange&>(stateChange);
PFMatchmakingTicketStatus status;
if (SUCCEEDED(PFMatchmakingTicketGetStatus(ticketStatusChanged.ticket, &status)))
{
printf("Ticket status is now: %i.\n", status);
}
break;
}
case PFMatchmakingStateChangeType::TicketCompleted:
{
const auto& ticketCompleted = static_cast<const PFMatchmakingTicketCompletedStateChange&>(stateChange);
printf("PFMatchmaking completed with Result 0x%08x.\n", ticketCompleted.result);
if (FAILED(ticketCompleted.result))
{
// On failure, we must record the HRESULT so we can return the state change(s) and then bail
// out of this function.
hrTicketError = ticketCompleted.result;
}
break;
}
}
}
hr = PFMultiplayerFinishProcessingMatchmakingStateChanges(g_pfmHandle, stateChangeCount, stateChanges);
RETURN_IF_FAILED(hr);
// Now that we've returned the state change(s), bail out if we detected ticket failure.
RETURN_IF_FAILED(hrTicketError);
매치 가져오기
PFMatchmakingStateChangeType::TicketCompleted 상태 변경을 수신한 후 PFMatchmakingTicketGetMatch를 호출하여 매치 세부 정보를 가져옵니다. 이러한 세부 정보에는 매치 ID, 함께 매치된 사용자, 매치 선호 지역, 매치와 관련된 로비의 배열 문자열이 포함됩니다.
PFMatchmakingMatchDetails 구조체에서 필요한 정보를 검색한 후에는 PFMultiplayerDestroyMatchmakingTicket을 사용하여 티켓을 파기해야 합니다.
매치 메이킹 클라이언트 SDK를 사용하는 예
const PFMatchmakingMatchDetails* match;
HREULT hr = PFMatchmakingTicketGetMatch(ticket, &match);
RETURN_IF_FAILED(hr);
std::string matchId = match->matchId;
std::string lobbyArrangementString = match->lobbyArrangementString;
PFMultiplayerDestroyMatchmakingTicket(g_pfmHandle, ticket);
매치 메이킹 티켓 취소
어떤 이유로 클라이언트가 PFMatchmakingTicketConfiguration
에 설정된 시간 초과 전에 매치 메이킹 프로세스를 취소하려는 경우 티켓 핸들을 사용하여 PFMatchmakingTicketCancel을 호출합니다.
이 API를 호출해도 티켓이 취소된다는 보장은 없습니다. 취소가 처리되기 전에 티켓이 완료될 수 있거나 네트워킹 또는 서비스 오류로 인해 취소 요청이 실패할 수 있습니다. 티켓 결과를 얻으려면 여전히 매치 메이킹 상태 변경을 처리해야 합니다.
매치 메이킹 클라이언트 SDK를 사용하는 예
HRESULT hr = PFMatchmakingTicketCancel(ticket);
(선택 사항) 플레이어를 로비에 함께 연결
플레이어가 일치하면 로비에서 함께 참여할 수 있습니다. 일치 티켓의 PFMatchmakingMatchDetails에는 사용자를 동일한 로비에 참여시키는 데 사용할 수 있는 lobbyArrangementString 필드가 포함되어 있습니다.
로비와 매치 메이킹이 함께 상호 작용하는 방법에 대한 자세한 내용은 로비와 매치 메이킹을 함께 사용을 참조하세요.
PlayFab 로비에 대한 자세한 내용은 PlayFab 로비 개요를 참조하세요.
매치 메이킹 클라이언트 SDK를 사용하는 예
const PFMatchmakingMatchDetails* match;
HREULT hr = PFMatchmakingTicketGetMatch(ticket, &match);
RETURN_IF_FAILED(hr);
std::string matchId = match->matchId;
std::string lobbyArrangementString = match->lobbyArrangementString;
PFMultiplayerDestroyMatchmakingTicket(g_pfmHandle, ticket);
PFLobbyHandle lobby;
RETURN_IF_FAILED_HR(PFMultiplayerJoinArrangedLobby(
m_pfmHandle,
&joiningUser,
lobbyArrangementString,
&joinConfig,
nullptr, // optional asyncContext
&lobby));
결론
이 빠른 시작을 사용하면 이제 게임에서 성공적인 매치 메이킹 플로우를 얻을 수 있습니다. 또한 다음 사항을 고려해야 합니다.
- 타이틀이 그룹 구성을 처리하는 방법.
- 사용자가 매치를 기다리는 동안 표시되는 타이틀.
- 실패 및 다시 시도를 처리하는 방법.