Put it all together - Quick match with peer-to-peer - (Unity module)
AccelByte Gaming Services (AGS) SDK for Unity does not support P2P on WebGL. This module cannot be used in WebGL builds.
Connect the UI to start, cancel, and display the matchmaking status
-
Open
MatchmakingP2PMenu_Starter
class and define a variable to store the wrapper you created.private MatchmakingP2PWrapper_Starter matchmakingP2PWrapper;
-
Create a new function to register callback functions to handle the matchmaking events. You'll create these callback functions in the next steps.
private void RegisterMatchmakingEvents()
{
if (!matchmakingP2PWrapper) return;
MatchmakingEssentialsWrapper.OnMatchFound += OnMatchmakingComplete;
MatchmakingEssentialsWrapper.OnMatchmakingExpired += OnMatchmakingExpired;
MatchmakingEssentialsWrapper.OnSessionInviteReceived += OnSessionInviteReceived;
} -
Create a new function to clear the callback functions registration to stop listening to the matchmaking events.
private void ClearMatchmakingEvents()
{
if (!matchmakingP2PWrapper) return;
MatchmakingEssentialsWrapper.OnMatchFound -= OnMatchmakingComplete;
MatchmakingEssentialsWrapper.OnMatchmakingExpired -= OnMatchmakingExpired;
MatchmakingEssentialsWrapper.OnSessionInviteReceived -= OnSessionInviteReceived;
} -
Replace the
StartMatchmaking()
function with the code below. This function sends a request to start matchmaking using the match pool based on the selected game mode. The match pool is retrieved usingGetGameSessionRequestModel()
from theAccelByteWarsOnlineSessionModels
class.private void StartMatchmaking()
{
// Get the match pool name from the game config.
SessionV2GameSessionCreateRequest request =
AccelByteWarsOnlineSessionModels.GetGameSessionRequestModel(MatchmakingMenu.SelectedGameMode, GameSessionServerType.PeerToPeer);
if (request == null)
{
BytewarsLogger.LogWarning("Failed to start matchmaking. Session type is not supported.");
stateSwitcher.ErrorMessage = InvalidSessionTypeMessage;
stateSwitcher.SetState(MatchmakingMenuState.Error);
return;
}
// Reregister matchmaking events.
ClearMatchmakingEvents();
RegisterMatchmakingEvents();
// Start matchmaking
stateSwitcher.SetState(MatchmakingMenuState.StartMatchmaking);
matchmakingP2PWrapper.StartMatchmaking(request.matchPool, OnStartMatchmakingComplete);
} -
Create the callback function to handle when matchmaking starts. If the request fails, it switches the menu to the error state. Otherwise, it binds the cancel button to cancel matchmaking and switches the menu to the finding match state.
private void OnStartMatchmakingComplete(Result<MatchmakingV2CreateTicketResponse> result)
{
if (result.IsError)
{
ClearMatchmakingEvents();
stateSwitcher.ErrorMessage = result.Error.Message;
stateSwitcher.SetState(MatchmakingMenuState.Error);
return;
}
stateSwitcher.OnCancelButtonClicked = () => CancelMatchmaking(result.Value.matchTicketId);
stateSwitcher.SetState(MatchmakingMenuState.FindingMatch);
} -
Replace the
CancelMatchmaking()
function with the code below. This sends a request to cancel matchmaking and switches the menu to the cancel matchmaking state.private void CancelMatchmaking(string matchTicketId)
{
ClearMatchmakingEvents();
stateSwitcher.SetState(MatchmakingMenuState.CancelMatchmaking);
matchmakingP2PWrapper.CancelMatchmaking(matchTicketId, OnCancelMatchmakingComplete);
} -
Create the callback function to handle when matchmaking is canceled. If the request fails, it switches the menu to the error state. Otherwise, it closes the menu and returns to the previous menu.
private void OnCancelMatchmakingComplete(Result result)
{
if (result.IsError)
{
stateSwitcher.ErrorMessage = result.Error.Message;
stateSwitcher.SetState(MatchmakingMenuState.Error);
return;
}
MenuManager.Instance.OnBackPressed();
} -
Create a new function to leave a session. Use this to leave the session created by matchmaking to allow the player to cancel matchmaking progress.
private void LeaveSession(string sessionId)
{
ClearMatchmakingEvents();
stateSwitcher.SetState(MatchmakingMenuState.LeaveMatch);
matchmakingP2PWrapper.LeaveGameSession(sessionId, OnLeaveSessionComplete);
} -
Create the callback function to handle when leave session completes. If the request fails, switch to error state. Otherwise, close the menu and return to the previous menu.
private void OnLeaveSessionComplete(Result result)
{
if (result.IsError)
{
stateSwitcher.ErrorMessage = result.Error.Message;
stateSwitcher.SetState(MatchmakingMenuState.Error);
return;
}
MenuManager.Instance.OnBackPressed();
} -
Create a function to join a session, allowing the player to join the session created upon matchmaking found.
private void JoinSession(string sessionId)
{
stateSwitcher.OnCancelButtonClicked = () => LeaveSession(sessionId);
stateSwitcher.SetState(MatchmakingMenuState.JoinMatch);
matchmakingP2PWrapper.JoinGameSession(sessionId, OnJoinSessionComplete);
} -
Create the callback function to switch the menu to the corresponding state when the session is joined.
private void OnJoinSessionComplete(Result<SessionV2GameSession> result)
{
// Abort if already attempt to cancel join the match.
if (stateSwitcher.CurrentState != MatchmakingMenuState.JoinMatch)
{
return;
}
if (result.IsError)
{
ClearMatchmakingEvents();
stateSwitcher.ErrorMessage = result.Error.Message;
stateSwitcher.SetState(MatchmakingMenuState.Error);
return;
}
stateSwitcher.SetState(MatchmakingMenuState.JoinedMatch);
} -
Create a function to reject a session invitation. Use this to allow the player to reject the session created upon matchmaking found.
private void RejectSessionInvite(string sessionId)
{
ClearMatchmakingEvents();
stateSwitcher.SetState(MatchmakingMenuState.RejectMatch);
matchmakingP2PWrapper.RejectGameSessionInvite(sessionId, OnRejectSessionInviteComplete);
} -
Create the callback function to handle when reject session invitation completes. If it fails, switch to error state. Otherwise, close the menu and return to the previous menu.
private void OnRejectSessionInviteComplete(Result result)
{
if (result.IsError)
{
stateSwitcher.ErrorMessage = result.Error.Message;
stateSwitcher.SetState(MatchmakingMenuState.Error);
return;
}
MenuManager.Instance.OnBackPressed();
} -
Create a callback function to handle when matchmaking found players to match. If it fails, switch to error state. Otherwise, switch to the match found state, indicating it waits for the session invitation from the backend.
private void OnMatchmakingComplete(Result<MatchmakingV2MatchFoundNotification> result)
{
if (result.IsError)
{
ClearMatchmakingEvents();
stateSwitcher.ErrorMessage = result.Error.Message;
stateSwitcher.SetState(MatchmakingMenuState.Error);
return;
}
MatchmakingEssentialsWrapper.OnMatchFound -= OnMatchmakingComplete;
// Only change the menu state if the session invite is not already received.
if (stateSwitcher.CurrentState != MatchmakingMenuState.JoinMatchConfirmation)
{
stateSwitcher.SetState(MatchmakingMenuState.MatchFound);
}
} -
Create a callback function to handle when session invitation is received. This happens upon matchmaking finding a match. It rebinds join and reject buttons to join or reject the session respectively, then switches the menu to join confirmation state.
private async void OnSessionInviteReceived(Result<SessionV2GameInvitationNotification> result)
{
if (result.IsError)
{
ClearMatchmakingEvents();
stateSwitcher.ErrorMessage = result.Error.Message;
stateSwitcher.SetState(MatchmakingMenuState.Error);
return;
}
MatchmakingEssentialsWrapper.OnSessionInviteReceived -= OnSessionInviteReceived;
stateSwitcher.OnJoinButtonClicked = () => JoinSession(result.Value.sessionId);
stateSwitcher.OnRejectButtonClicked = () => RejectSessionInvite(result.Value.sessionId);
/* Delay a bit to prevent menu state overlap.
* Since the session invite and match found event may be received at the same time. */
await UniTask.Delay(StateChangeDelay * 1000);
stateSwitcher.SetState(MatchmakingMenuState.JoinMatchConfirmation);
} -
Create a callback function to handle when matchmaking fails due to ticket expiration.
private void OnMatchmakingExpired(Result<MatchmakingV2TicketExpiredNotification> result)
{
ClearMatchmakingEvents();
stateSwitcher.ErrorMessage = result.IsError ? result.Error.Message : MatchmakingExpiredMessage;
stateSwitcher.SetState(MatchmakingMenuState.Error);
} -
Replace the pre-defined
OnEnable()
function with the following code to initialize the wrapper and start matchmaking when the menu displays.private void OnEnable()
{
matchmakingP2PWrapper ??= TutorialModuleManager.Instance.GetModuleClass<MatchmakingP2PWrapper_Starter>();
if (matchmakingP2PWrapper) StartMatchmaking();
} -
Finally, replace the pre-defined
OnDisable()
function with the code below to stop listening to matchmaking events when the menu closes.private void OnDisable()
{
ClearMatchmakingEvents();
}
Resources
-
The files used in this tutorial are available in the Unity Byte Wars GitHub repository.