Put it all together - Create joinable sessions with dedicated servers - (Unity module)
Connect the UI to create and join match sessions
-
Open
CreateMatchSessionDSMenu_Starter
class and define a variable to store the wrapper you created.private MatchSessionDSWrapper_Starter matchSessionDSWrapper;
-
Create a new function to register callback functions to handle the game session events. You'll create these callback functions in the next steps.
private void RegisterMatchSessionEvents()
{
if (!matchSessionDSWrapper) return;
MatchSessionEssentialsWrapper.OnDSStatusChanged += OnDSStatusChanged;
} -
Create a new function to clear the callback functions registration to stop listening to the game session events.
private void ClearMatchSessionEvents()
{
if (!matchSessionDSWrapper) return;
MatchSessionEssentialsWrapper.OnDSStatusChanged -= OnDSStatusChanged;
} -
Replace the
CreateMatchSession()
function with the code below. This function sends a request to create a new game session using the session template based on the selected game mode. The session template is retrieved usingGetGameSessionRequestModel()
from theAccelByteWarsOnlineSessionModels
class.private void CreateMatchSession()
{
// Get the session template name from the game config.
SessionV2GameSessionCreateRequest request =
AccelByteWarsOnlineSessionModels.GetGameSessionRequestModel(CreateMatchSessionMenu.SelectedGameMode, GameSessionServerType.DedicatedServerAMS);
if (request == null)
{
BytewarsLogger.LogWarning("Failed to create match session. Session type is not supported.");
stateSwitcher.ErrorMessage = InvalidSessionTypeMessage;
stateSwitcher.SetState(MatchSessionMenuState.Error);
return;
}
// Reregister match session events.
ClearMatchSessionEvents();
RegisterMatchSessionEvents();
// Create a new match session.
stateSwitcher.SetState(MatchSessionMenuState.CreateMatch);
matchSessionDSWrapper.CreateGameSession(request, OnJoinSessionComplete);
} -
Replace the
JoinMatchSession()
function with the code below. This function sends a request to join a game session by its session ID.private void JoinMatchSession(string sessionId)
{
// Reregister match session events.
ClearMatchSessionEvents();
RegisterMatchSessionEvents();
stateSwitcher.SetState(MatchSessionMenuState.JoinMatch);
matchSessionDSWrapper.JoinGameSession(sessionId, OnJoinSessionComplete);
} -
Create the callback function to handle when a game session is created or joined. If successful, it switches the menu to the join state and waits for the server.
private async void OnJoinSessionComplete(Result<SessionV2GameSession> result)
{
// Abort if already attempt to cancel join the match.
if (stateSwitcher.CurrentState is
not (MatchSessionMenuState.CreateMatch or MatchSessionMenuState.JoinMatch))
{
return;
}
if (result.IsError)
{
ClearMatchSessionEvents();
stateSwitcher.ErrorMessage = result.Error.Message;
stateSwitcher.SetState(MatchSessionMenuState.Error);
return;
}
stateSwitcher.SetState(MatchSessionMenuState.JoinedMatch);
await UniTask.Delay(StateChangeDelay * 1000); // Delay a bit before changing menu state.
stateSwitcher.SetState(MatchSessionMenuState.RequestingServer);
} -
Replace the
LeaveMatchSession()
function with the code below. This function checks whether there is a valid session to leave. If not, it simply close the menu and return to the previous menu.private void LeaveMatchSession(string sessionId)
{
ClearMatchSessionEvents();
// Simply return from the menu if the session is empty.
if (string.IsNullOrEmpty(sessionId))
{
MenuManager.Instance.OnBackPressed();
return;
}
stateSwitcher.SetState(MatchSessionMenuState.LeaveMatch);
matchSessionDSWrapper.LeaveGameSession(sessionId, OnLeaveMatchSessionComplete);
} -
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 OnLeaveMatchSessionComplete(Result result)
{
if (result.IsError && result.Error.Code != ErrorCode.SessionIdNotFound)
{
stateSwitcher.ErrorMessage = result.Error.Message;
stateSwitcher.SetState(MatchSessionMenuState.Error);
return;
}
MenuManager.Instance.OnBackPressed();
} -
Create a callback function to handle when dedicated server information is received. It displays the corresponding menu state based on the dedicated server status.
private void OnDSStatusChanged(Result<SessionV2DsStatusUpdatedNotification> result)
{
if (result.IsError)
{
ClearMatchSessionEvents();
stateSwitcher.ErrorMessage = result.Error.Message;
stateSwitcher.SetState(MatchSessionMenuState.Error);
return;
}
SessionV2DsInformation dsInfo = result.Value.session.dsInformation;
switch (dsInfo.StatusV2)
{
case SessionV2DsStatus.AVAILABLE:
ClearMatchSessionEvents();
break;
case SessionV2DsStatus.FAILED_TO_REQUEST:
case SessionV2DsStatus.ENDED:
case SessionV2DsStatus.UNKNOWN:
ClearMatchSessionEvents();
stateSwitcher.ErrorMessage = FailedToFindServerMessage;
stateSwitcher.SetState(MatchSessionMenuState.Error);
break;
default:
stateSwitcher.SetState(MatchSessionMenuState.RequestingServer);
break;
}
} -
Next, replace the pre-defined
OnEnable()
function with the code below. This code initialize the wrapper first then determine whether to create or join a game session when the menu is displayed. It also rebinds the retry and cancel buttons accordingly.private void OnEnable()
{
matchSessionDSWrapper ??= TutorialModuleManager.Instance.GetModuleClass<MatchSessionDSWrapper_Starter>();
if (!matchSessionDSWrapper)
{
return;
}
if (sessionToJoin == null)
{
stateSwitcher.OnRetryButtonClicked = CreateMatchSession;
stateSwitcher.OnCancelButtonClicked = () => LeaveMatchSession(AccelByteWarsOnlineSession.CachedSession.id);
CreateMatchSession();
}
else
{
stateSwitcher.OnRetryButtonClicked = () => JoinMatchSession(sessionToJoin.Session.id);
stateSwitcher.OnCancelButtonClicked = () => LeaveMatchSession(sessionToJoin.Session.id);
JoinMatchSession(sessionToJoin.Session.id);
}
} -
Finally, replace the pre-defined
OnDisable()
function with the code below to stop listening to game session events when the menu closes.private void OnDisable()
{
sessionToJoin = null;
ClearMatchSessionEvents();
}
Resources
-
The files used in this tutorial are available in the Unity Byte Wars GitHub repository.