fix: unable to quit application with application exit or in-game exit button [MTT-7003] by fernando-cortez · Pull Request #863 · Unity-Technologies/com.unity.multiplayer.samples.coop
Description
This PR fixes the issue of not being able to quit the application after a game session.
This was due to not unsubscribing to the Application.wantsToQuit callback when attempting to quit. The callback would fire on a client when quitting, and in the attempt of quitting, would invoke m_LobbyServiceFacade.EndTracking(), that call would return an error, the application would invoke Application.Quit, and the loop would continue, stuck in a loop.
This PR simply unsubscribes to the Application.wantsToQuit callback when attempting to quit, invoking the cleanup coroutine only once.
Issue Number(s)
How To Test
- Host with one built executable
- Join with another executable
- Proceed in-game after Character Selection
- Have host end session through in-game buttons
- As the client now in the Main Menu scene, quit the application via the OS-level quit button (or in-game button)
- See that the client is able to quit the application properly.
Contribution checklist
- [ N/A ] Tests have been added for boss room and/or utilities pack
- Release notes have been added to the project changelog file and/or package changelog file
- Pull request has a meaningful description of its purpose
- All commits are accompanied by meaningful commit messages
- JIRA ticket ID is in the PR title or at least one commit message
- Include the ticket ID number within the body message of the PR to create a hyperlink
- [ N/A ] An Index entry has been added in readme.md if applicable
Open Question
This is more of a design question, but I'm noticing that on certain async Lobby requests, namely ones for deletion and leaving, the internal Lobby reference isn't cleared if the operation fails. This can happen if a client has been removed from a Lobby -> they try to leave that Lobby -> the Lobby doesn't exist -> async operation fails -> ResetLobby() is not invoked because of this.
So then the client is technically not part of a Lobby, but LobbyServiceFacade.CurrentUnityLobby is still not null. This can result in various attempts to leave a lobby when the application is quit, since LobbyServiceFacade.CurrentUnityLobby is not cleared.
I propose to refactor LobbyServiceFacade.LeaveLobbyAsync from:
public async void LeaveLobbyAsync()
{
string uasId = AuthenticationService.Instance.PlayerId;
try
{
await m_LobbyApiInterface.RemovePlayerFromLobby(uasId, m_LocalLobby.LobbyID);
ResetLobby();
}
catch (LobbyServiceException e)
{
// If Lobby is not found and if we are not the host, it has already been deleted. No need to publish the error here.
if (e.Reason != LobbyExceptionReason.LobbyNotFound && !m_LocalUser.IsHost)
{
PublishError(e);
}
}
}
to something like:
public async void LeaveLobbyAsync()
{
string uasId = AuthenticationService.Instance.PlayerId;
try
{
await m_LobbyApiInterface.RemovePlayerFromLobby(uasId, m_LocalLobby.LobbyID);
}
catch (LobbyServiceException e)
{
// If Lobby is not found and if we are not the host, it has already been deleted. No need to publish the error here.
if (e.Reason != LobbyExceptionReason.LobbyNotFound && !m_LocalUser.IsHost)
{
PublishError(e);
}
}
finally
{
ResetLobby();
}
}
so that the Lobby is cleared regardless of async operation result.
Let me know your thoughts on this proposal. It would similarly be applied to the deletion async operation.