From 984cb292ea789ae059b5fb3525a1836ff18f06ec Mon Sep 17 00:00:00 2001 From: David Woodruff Date: Fri, 16 Apr 2021 11:13:18 -0400 Subject: [PATCH 1/4] fixing issue where host quitting strands some clients in the game. Also fixed issue where no disconnect message was shown in MainMenu. --- .../Prefabs/State/BossRoomState.prefab | 2 +- .../Prefabs/State/CharSelectState.prefab | 2 +- .../Prefabs/State/MainMenuState.prefab | 45 +++++++++++++++++++ .../Prefabs/State/MainMenuState.prefab.meta | 7 +++ .../Prefabs/State/PostGameState.prefab | 2 +- Assets/BossRoom/Scenes/MainMenu.unity | 4 +- .../Client/Game/State/ClientMainMenuState.cs | 44 ++++++++++++++++++ .../Client/Game/State/ClientPostGameState.cs | 12 +++++ .../Scripts/Client/Net/ClientGameNetPortal.cs | 28 ++++++------ .../BossRoom/Scripts/Client/UI/MainMenuUI.cs | 11 +++++ ProjectSettings/TagManager.asset | 4 +- 11 files changed, 139 insertions(+), 22 deletions(-) create mode 100644 Assets/BossRoom/Prefabs/State/MainMenuState.prefab create mode 100644 Assets/BossRoom/Prefabs/State/MainMenuState.prefab.meta diff --git a/Assets/BossRoom/Prefabs/State/BossRoomState.prefab b/Assets/BossRoom/Prefabs/State/BossRoomState.prefab index 2d6af40f4..8f13b4bab 100644 --- a/Assets/BossRoom/Prefabs/State/BossRoomState.prefab +++ b/Assets/BossRoom/Prefabs/State/BossRoomState.prefab @@ -14,7 +14,7 @@ GameObject: - component: {fileID: 5762482089640033414} m_Layer: 0 m_Name: BossRoomState - m_TagString: Untagged + m_TagString: ActiveState m_Icon: {fileID: 0} m_NavMeshLayer: 0 m_StaticEditorFlags: 0 diff --git a/Assets/BossRoom/Prefabs/State/CharSelectState.prefab b/Assets/BossRoom/Prefabs/State/CharSelectState.prefab index 74a34eca3..ef407404d 100644 --- a/Assets/BossRoom/Prefabs/State/CharSelectState.prefab +++ b/Assets/BossRoom/Prefabs/State/CharSelectState.prefab @@ -15,7 +15,7 @@ GameObject: - component: {fileID: 1092063945021251778} m_Layer: 0 m_Name: CharSelectState - m_TagString: Untagged + m_TagString: ActiveState m_Icon: {fileID: 0} m_NavMeshLayer: 0 m_StaticEditorFlags: 0 diff --git a/Assets/BossRoom/Prefabs/State/MainMenuState.prefab b/Assets/BossRoom/Prefabs/State/MainMenuState.prefab new file mode 100644 index 000000000..0272ceef3 --- /dev/null +++ b/Assets/BossRoom/Prefabs/State/MainMenuState.prefab @@ -0,0 +1,45 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!1 &8576152884213668003 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 8576152884213668001} + - component: {fileID: 8576152884213668000} + m_Layer: 0 + m_Name: MainMenuState + m_TagString: ActiveState + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &8576152884213668001 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 8576152884213668003} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: [] + m_Father: {fileID: 0} + m_RootOrder: 0 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!114 &8576152884213668000 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 8576152884213668003} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: ab10fd7c6aa7d36438f5ac1c0ebfadbb, type: 3} + m_Name: + m_EditorClassIdentifier: diff --git a/Assets/BossRoom/Prefabs/State/MainMenuState.prefab.meta b/Assets/BossRoom/Prefabs/State/MainMenuState.prefab.meta new file mode 100644 index 000000000..3aea49d17 --- /dev/null +++ b/Assets/BossRoom/Prefabs/State/MainMenuState.prefab.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 30b6e45e8e2b596449e225cafe2a05a2 +PrefabImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/BossRoom/Prefabs/State/PostGameState.prefab b/Assets/BossRoom/Prefabs/State/PostGameState.prefab index a0e1b1068..a11e02318 100644 --- a/Assets/BossRoom/Prefabs/State/PostGameState.prefab +++ b/Assets/BossRoom/Prefabs/State/PostGameState.prefab @@ -15,7 +15,7 @@ GameObject: - component: {fileID: 4223400095609434710} m_Layer: 0 m_Name: PostGameState - m_TagString: Untagged + m_TagString: ActiveState m_Icon: {fileID: 0} m_NavMeshLayer: 0 m_StaticEditorFlags: 0 diff --git a/Assets/BossRoom/Scenes/MainMenu.unity b/Assets/BossRoom/Scenes/MainMenu.unity index 6f51c75a5..c9824ac44 100644 --- a/Assets/BossRoom/Scenes/MainMenu.unity +++ b/Assets/BossRoom/Scenes/MainMenu.unity @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:fb3cb49cb437750c9aac36521dcb84ded801db7c4300a21ff90ab4542951d95b -size 53379 +oid sha256:86946e369c648bac2d269fb4bbf3cbe6274f028119b17053f2c8ccfe57ad9fdc +size 52973 diff --git a/Assets/BossRoom/Scripts/Client/Game/State/ClientMainMenuState.cs b/Assets/BossRoom/Scripts/Client/Game/State/ClientMainMenuState.cs index 2602d53b4..d6bec4686 100644 --- a/Assets/BossRoom/Scripts/Client/Game/State/ClientMainMenuState.cs +++ b/Assets/BossRoom/Scripts/Client/Game/State/ClientMainMenuState.cs @@ -11,6 +11,50 @@ namespace BossRoom.Client /// public class ClientMainMenuState : GameStateBehaviour { + /// + /// Used in concert with SetTransitionReason to let code that triggers transition to the MainMenu scene set context + /// for why the transition occurred. This is then used to display an appropriate message to the user in the UI. + /// + public enum TransitionReason + { + Undefined, //no reason has been set. + UserRequested, //user explicitly requested a disconnect. + Disconnect, //client unexpectedly lost connection with host. + } + + private static TransitionReason s_TransitionReason; + + /// + /// Set this to have the MainMenu display a MessageBox to the user on re-entering the MainMenu. Useful for displaying error states. + /// + public static void SetTransitionReason( TransitionReason reason ) + { + s_TransitionReason = reason; + } + + /// + /// Has a TransitionReason already be set? (The TransitionReason provides context for why someone transition back to the MainMenu, and is a one-use item + /// that is unset as soon as it is read). + /// + public static bool HasTransitionReason => s_TransitionReason != TransitionReason.Undefined; + + /// + /// MainMenuUI should invoke this on start, and display a message to the user if not Undefined + /// + /// TransitionReason set by whoever triggered the scene transition to main menu, or undefined if none. + public TransitionReason ReadAndUnsetTransitionReason() + { + var reason = s_TransitionReason; + s_TransitionReason = TransitionReason.Undefined; + return reason; + } + + protected override void OnDestroy() + { + base.OnDestroy(); + s_TransitionReason = TransitionReason.Undefined; + } + public override GameState ActiveState { get { return GameState.MainMenu; } } public override void NetworkStart() diff --git a/Assets/BossRoom/Scripts/Client/Game/State/ClientPostGameState.cs b/Assets/BossRoom/Scripts/Client/Game/State/ClientPostGameState.cs index 5fcd9fedf..345428a8a 100644 --- a/Assets/BossRoom/Scripts/Client/Game/State/ClientPostGameState.cs +++ b/Assets/BossRoom/Scripts/Client/Game/State/ClientPostGameState.cs @@ -8,6 +8,18 @@ public class ClientPostGameState : GameStateBehaviour { public override GameState ActiveState { get { return GameState.PostGame; } } + protected override void Start() + { + base.Start(); + + //it is common for the user to get dumped back to main menu from here (i.e., if the host decides not to play again), and + //it is a little funny to display a "Connection to Host Lost" message in that case. The best thing would probably be to + //display a "Host Abandoned the Game" message, but this would require some more plumbing (an RPC from the host before it quit, + //containing that information). + //In the meantime, we just set "UserRequested" to suppress the Disconnected error popup. + ClientMainMenuState.SetTransitionReason(ClientMainMenuState.TransitionReason.UserRequested); + } + public override void NetworkStart() { base.NetworkStart(); diff --git a/Assets/BossRoom/Scripts/Client/Net/ClientGameNetPortal.cs b/Assets/BossRoom/Scripts/Client/Net/ClientGameNetPortal.cs index 2e69faacd..71c3e5838 100644 --- a/Assets/BossRoom/Scripts/Client/Net/ClientGameNetPortal.cs +++ b/Assets/BossRoom/Scripts/Client/Net/ClientGameNetPortal.cs @@ -54,7 +54,7 @@ private void NetworkStart() //only do this if a pure client, so as not to overlap with host behavior in ServerGameNetPortal. m_Portal.UserDisconnectRequested += OnUserDisconnectRequest; } - m_Portal.NetManager.OnClientDisconnectCallback += OnClientDisconnect; + SceneManager.sceneLoaded += OnSceneLoaded; } } @@ -71,23 +71,11 @@ private void OnUserDisconnectRequest() { if( m_Portal.NetManager.IsClient ) { + ClientMainMenuState.SetTransitionReason(ClientMainMenuState.TransitionReason.UserRequested); m_Portal.NetManager.StopClient(); } } - /// - /// Invoked whenever a client disconnects from the host. - /// - private void OnClientDisconnect(ulong clientId) - { - if( clientId == m_Portal.NetManager.LocalClientId ) - { - SceneManager.sceneLoaded -= OnSceneLoaded; - m_Portal.UserDisconnectRequested -= OnUserDisconnectRequest; - m_Portal.NetManager.OnClientDisconnectCallback -= OnClientDisconnect; - } - } - private void OnConnectFinished(ConnectStatus status) { //on success, there is nothing to do (the MLAPI scene management system will take us to the next scene). @@ -99,8 +87,13 @@ private void OnConnectFinished(ConnectStatus status) private void OnDisconnectOrTimeout(ulong clientID) { - if(clientID == MLAPI.NetworkManager.Singleton.LocalClientId ) + // we could also check whether the disconnect was us or the host, but the "interesting" question is whether + //following the disconnect, we're no longer a Connected Client, so we just explicitly check that scenario. + if ( !MLAPI.NetworkManager.Singleton.IsConnectedClient ) { + SceneManager.sceneLoaded -= OnSceneLoaded; + m_Portal.UserDisconnectRequested -= OnUserDisconnectRequest; + //On a client disconnect we want to take them back to the main menu. //We have to check here in SceneManager if our active scene is the main menu, as if it is, it means we timed out rather than a raw disconnect; if (UnityEngine.SceneManagement.SceneManager.GetActiveScene().name != "MainMenu") @@ -108,6 +101,11 @@ private void OnDisconnectOrTimeout(ulong clientID) // we're not at the main menu, so we obviously had a connection before... thus, we aren't in a timeout scenario. // Just shut down networking and switch back to main menu. MLAPI.NetworkManager.Singleton.Shutdown(); + if( !ClientMainMenuState.HasTransitionReason ) + { + //disconnect that happened for some other reason than user UI interaction--should display a message. + ClientMainMenuState.SetTransitionReason(ClientMainMenuState.TransitionReason.Disconnect); + } SceneManager.LoadScene("MainMenu"); } else diff --git a/Assets/BossRoom/Scripts/Client/UI/MainMenuUI.cs b/Assets/BossRoom/Scripts/Client/UI/MainMenuUI.cs index fd05216c8..b36092c47 100644 --- a/Assets/BossRoom/Scripts/Client/UI/MainMenuUI.cs +++ b/Assets/BossRoom/Scripts/Client/UI/MainMenuUI.cs @@ -33,6 +33,17 @@ void Start() m_ClientNetPortal.NetworkTimedOut += OnNetworkTimeout; m_ClientNetPortal.ConnectFinished += OnConnectFinished; + + var stateGO = GameObject.FindGameObjectWithTag("ActiveState"); + var mainMenuState = stateGO != null ? stateGO.GetComponent() : null; + if( mainMenuState != null ) + { + var transitionReason = mainMenuState.ReadAndUnsetTransitionReason(); + if( transitionReason == ClientMainMenuState.TransitionReason.Disconnect ) + { + m_ResponsePopup.SetupNotifierDisplay("Disconnected From Host", "The connection to the Host was lost", false, true ); + } + } } public void OnHostClicked() diff --git a/ProjectSettings/TagManager.asset b/ProjectSettings/TagManager.asset index f599ad253..b243daabb 100644 --- a/ProjectSettings/TagManager.asset +++ b/ProjectSettings/TagManager.asset @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:bd98f6f2c43732be288a6ea3709f3f35b2cb5a720c64f605b322798373557c8b -size 549 +oid sha256:20c968555c901eab94e878b1e5d0131e6a749b2c73203b2a1a16f6ac22733ee8 +size 565 From 600896249f2aaa0e26f6f152542a4dab8bbe7f40 Mon Sep 17 00:00:00 2001 From: David Woodruff Date: Tue, 20 Apr 2021 16:22:54 -0400 Subject: [PATCH 2/4] adding missed meta file --- .../Third Party Notices.md.meta | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 Packages/com.unity.multiplayer.samples.coop/Third Party Notices.md.meta diff --git a/Packages/com.unity.multiplayer.samples.coop/Third Party Notices.md.meta b/Packages/com.unity.multiplayer.samples.coop/Third Party Notices.md.meta new file mode 100644 index 000000000..626bc1164 --- /dev/null +++ b/Packages/com.unity.multiplayer.samples.coop/Third Party Notices.md.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: bd16abfad80aa0a46a5c1914f7a336be +TextScriptImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: From e83cf9826d6f34cccadb2086f88a5b232920d7e3 Mon Sep 17 00:00:00 2001 From: David Woodruff Date: Tue, 20 Apr 2021 20:49:46 -0400 Subject: [PATCH 3/4] removing transitionreason in favor of a new DisconnectReason class that hangs off ClientGameNetPortal --- .../Prefabs/State/BossRoomState.prefab | 11 ++-- .../Prefabs/State/CharSelectState.prefab | 2 +- .../Prefabs/State/MainMenuState.prefab | 2 +- .../Prefabs/State/PostGameState.prefab | 2 +- .../Client/Game/State/ClientMainMenuState.cs | 45 ---------------- .../Client/Game/State/ClientPostGameState.cs | 5 +- .../Scripts/Client/Net/ClientGameNetPortal.cs | 14 +++-- .../Scripts/Client/Net/DisconnectReason.cs | 53 +++++++++++++++++++ .../Client/Net/DisconnectReason.cs.meta | 11 ++++ .../BossRoom/Scripts/Client/UI/MainMenuUI.cs | 10 +--- ProjectSettings/TagManager.asset | 4 +- 11 files changed, 89 insertions(+), 70 deletions(-) create mode 100644 Assets/BossRoom/Scripts/Client/Net/DisconnectReason.cs create mode 100644 Assets/BossRoom/Scripts/Client/Net/DisconnectReason.cs.meta diff --git a/Assets/BossRoom/Prefabs/State/BossRoomState.prefab b/Assets/BossRoom/Prefabs/State/BossRoomState.prefab index 3c909f291..45f7dff8b 100644 --- a/Assets/BossRoom/Prefabs/State/BossRoomState.prefab +++ b/Assets/BossRoom/Prefabs/State/BossRoomState.prefab @@ -15,7 +15,7 @@ GameObject: - component: {fileID: 2113376856512980659} m_Layer: 0 m_Name: BossRoomState - m_TagString: ActiveState + m_TagString: Untagged m_Icon: {fileID: 0} m_NavMeshLayer: 0 m_StaticEditorFlags: 0 @@ -83,8 +83,7 @@ MonoBehaviour: m_Script: {fileID: 11500000, guid: 927521835ae055247b17e4abe805b4ab, type: 3} m_Name: m_EditorClassIdentifier: - m_PlayerPrefab: {fileID: 6009713983291384767, guid: 8237adf32a9b6de4892e6febe6b4bdef, - type: 3} + m_PlayerPrefab: {fileID: 6009713983291384767, guid: 8237adf32a9b6de4892e6febe6b4bdef, type: 3} m_PlayerSpawnPoints: - {fileID: 6319832178442273571} - {fileID: 374135395555381814} @@ -106,10 +105,8 @@ MonoBehaviour: m_Script: {fileID: 11500000, guid: ab1e76745edfc434ab8154ad27efc5fd, type: 3} m_Name: m_EditorClassIdentifier: - m_EnemyPrefab: {fileID: 3713729372785093435, guid: 6cdd52f1fa2ed34469a487ae6477eded, - type: 3} - m_BossPrefab: {fileID: 3688950541947916326, guid: 365e94337fd10fe4ebde1906df413ac7, - type: 3} + m_EnemyPrefab: {fileID: 3713729372785093435, guid: 6cdd52f1fa2ed34469a487ae6477eded, type: 3} + m_BossPrefab: {fileID: 3688950541947916326, guid: 365e94337fd10fe4ebde1906df413ac7, type: 3} m_SpawnEnemyKeyCode: 101 m_SpawnBossKeyCode: 98 m_InstantQuitKeyCode: 113 diff --git a/Assets/BossRoom/Prefabs/State/CharSelectState.prefab b/Assets/BossRoom/Prefabs/State/CharSelectState.prefab index ef407404d..74a34eca3 100644 --- a/Assets/BossRoom/Prefabs/State/CharSelectState.prefab +++ b/Assets/BossRoom/Prefabs/State/CharSelectState.prefab @@ -15,7 +15,7 @@ GameObject: - component: {fileID: 1092063945021251778} m_Layer: 0 m_Name: CharSelectState - m_TagString: ActiveState + m_TagString: Untagged m_Icon: {fileID: 0} m_NavMeshLayer: 0 m_StaticEditorFlags: 0 diff --git a/Assets/BossRoom/Prefabs/State/MainMenuState.prefab b/Assets/BossRoom/Prefabs/State/MainMenuState.prefab index 0272ceef3..36b3aa2bd 100644 --- a/Assets/BossRoom/Prefabs/State/MainMenuState.prefab +++ b/Assets/BossRoom/Prefabs/State/MainMenuState.prefab @@ -12,7 +12,7 @@ GameObject: - component: {fileID: 8576152884213668000} m_Layer: 0 m_Name: MainMenuState - m_TagString: ActiveState + m_TagString: Untagged m_Icon: {fileID: 0} m_NavMeshLayer: 0 m_StaticEditorFlags: 0 diff --git a/Assets/BossRoom/Prefabs/State/PostGameState.prefab b/Assets/BossRoom/Prefabs/State/PostGameState.prefab index a11e02318..a0e1b1068 100644 --- a/Assets/BossRoom/Prefabs/State/PostGameState.prefab +++ b/Assets/BossRoom/Prefabs/State/PostGameState.prefab @@ -15,7 +15,7 @@ GameObject: - component: {fileID: 4223400095609434710} m_Layer: 0 m_Name: PostGameState - m_TagString: ActiveState + m_TagString: Untagged m_Icon: {fileID: 0} m_NavMeshLayer: 0 m_StaticEditorFlags: 0 diff --git a/Assets/BossRoom/Scripts/Client/Game/State/ClientMainMenuState.cs b/Assets/BossRoom/Scripts/Client/Game/State/ClientMainMenuState.cs index d6bec4686..929a6296b 100644 --- a/Assets/BossRoom/Scripts/Client/Game/State/ClientMainMenuState.cs +++ b/Assets/BossRoom/Scripts/Client/Game/State/ClientMainMenuState.cs @@ -11,50 +11,6 @@ namespace BossRoom.Client /// public class ClientMainMenuState : GameStateBehaviour { - /// - /// Used in concert with SetTransitionReason to let code that triggers transition to the MainMenu scene set context - /// for why the transition occurred. This is then used to display an appropriate message to the user in the UI. - /// - public enum TransitionReason - { - Undefined, //no reason has been set. - UserRequested, //user explicitly requested a disconnect. - Disconnect, //client unexpectedly lost connection with host. - } - - private static TransitionReason s_TransitionReason; - - /// - /// Set this to have the MainMenu display a MessageBox to the user on re-entering the MainMenu. Useful for displaying error states. - /// - public static void SetTransitionReason( TransitionReason reason ) - { - s_TransitionReason = reason; - } - - /// - /// Has a TransitionReason already be set? (The TransitionReason provides context for why someone transition back to the MainMenu, and is a one-use item - /// that is unset as soon as it is read). - /// - public static bool HasTransitionReason => s_TransitionReason != TransitionReason.Undefined; - - /// - /// MainMenuUI should invoke this on start, and display a message to the user if not Undefined - /// - /// TransitionReason set by whoever triggered the scene transition to main menu, or undefined if none. - public TransitionReason ReadAndUnsetTransitionReason() - { - var reason = s_TransitionReason; - s_TransitionReason = TransitionReason.Undefined; - return reason; - } - - protected override void OnDestroy() - { - base.OnDestroy(); - s_TransitionReason = TransitionReason.Undefined; - } - public override GameState ActiveState { get { return GameState.MainMenu; } } public override void NetworkStart() @@ -63,5 +19,4 @@ public override void NetworkStart() //fortunately we know you are a client, because all players are clients when sitting at the main menu screen. } } - } diff --git a/Assets/BossRoom/Scripts/Client/Game/State/ClientPostGameState.cs b/Assets/BossRoom/Scripts/Client/Game/State/ClientPostGameState.cs index 345428a8a..fe2d98919 100644 --- a/Assets/BossRoom/Scripts/Client/Game/State/ClientPostGameState.cs +++ b/Assets/BossRoom/Scripts/Client/Game/State/ClientPostGameState.cs @@ -1,3 +1,5 @@ +using UnityEngine; + namespace BossRoom.Client { /// @@ -17,7 +19,8 @@ protected override void Start() //display a "Host Abandoned the Game" message, but this would require some more plumbing (an RPC from the host before it quit, //containing that information). //In the meantime, we just set "UserRequested" to suppress the Disconnected error popup. - ClientMainMenuState.SetTransitionReason(ClientMainMenuState.TransitionReason.UserRequested); + var portalGO = GameObject.FindGameObjectWithTag("GameNetPortal"); + portalGO.GetComponent().DisconnectReason.SetDisconnectReason(DisconnectReasonType.UserRequested); } public override void NetworkStart() diff --git a/Assets/BossRoom/Scripts/Client/Net/ClientGameNetPortal.cs b/Assets/BossRoom/Scripts/Client/Net/ClientGameNetPortal.cs index 71c3e5838..e930472cc 100644 --- a/Assets/BossRoom/Scripts/Client/Net/ClientGameNetPortal.cs +++ b/Assets/BossRoom/Scripts/Client/Net/ClientGameNetPortal.cs @@ -18,6 +18,11 @@ public class ClientGameNetPortal : MonoBehaviour { private GameNetPortal m_Portal; + /// + /// If a disconnect occurred this will be populated with any contextual information that was available to explain why. + /// + public DisconnectReason DisconnectReason { get; private set; } = new DisconnectReason(); + /// /// Time in seconds before the client considers a lack of server response a timeout /// @@ -71,7 +76,7 @@ private void OnUserDisconnectRequest() { if( m_Portal.NetManager.IsClient ) { - ClientMainMenuState.SetTransitionReason(ClientMainMenuState.TransitionReason.UserRequested); + DisconnectReason.SetDisconnectReason(DisconnectReasonType.UserRequested); m_Portal.NetManager.StopClient(); } } @@ -101,10 +106,10 @@ private void OnDisconnectOrTimeout(ulong clientID) // we're not at the main menu, so we obviously had a connection before... thus, we aren't in a timeout scenario. // Just shut down networking and switch back to main menu. MLAPI.NetworkManager.Singleton.Shutdown(); - if( !ClientMainMenuState.HasTransitionReason ) + if( !DisconnectReason.HasTransitionReason ) { //disconnect that happened for some other reason than user UI interaction--should display a message. - ClientMainMenuState.SetTransitionReason(ClientMainMenuState.TransitionReason.Disconnect); + DisconnectReason.SetDisconnectReason(DisconnectReasonType.Disconnect); } SceneManager.LoadScene("MainMenu"); } @@ -127,7 +132,8 @@ private void OnDisconnectOrTimeout(ulong clientID) /// The port of the host to connect to. public static void StartClient(GameNetPortal portal, string ipaddress, int port) { - //DMW_NOTE: non-portable. We need to be updated when moving to UTP transport. + portal.GetComponent().DisconnectReason.Clear(); + var chosenTransport = NetworkManager.Singleton.gameObject.GetComponent().IpHostTransport; NetworkManager.Singleton.NetworkConfig.NetworkTransport = chosenTransport; diff --git a/Assets/BossRoom/Scripts/Client/Net/DisconnectReason.cs b/Assets/BossRoom/Scripts/Client/Net/DisconnectReason.cs new file mode 100644 index 000000000..57c7228db --- /dev/null +++ b/Assets/BossRoom/Scripts/Client/Net/DisconnectReason.cs @@ -0,0 +1,53 @@ +using System.Collections; +using System.Collections.Generic; +using UnityEngine; + +namespace BossRoom.Client +{ + /// + /// enum that records additional context for why a user was disconnected. The primary use case for this + /// is to allow the MainMenu to display an appropriate message after a disconnect event. + /// + public enum DisconnectReasonType + { + Undefined, //no reason has been set. + UserRequested, //user explicitly requested a disconnect. + Disconnect, //client unexpectedly lost connection with host. + } + + /// + /// This class provides some additional context for the connection managed by the ClientGameNetPortal. If a disconnect occurrs, or is expected to occur, client + /// code can set the reason why here. Then subsequent code can interrogate this class to get the disconnect reason, and display appropriate information to + /// the user, even after a scene transition has occurred. The state is set back to Undefined if a new connection is begun. + /// + public class DisconnectReason + { + /// + /// When a disconnect is detected (or expected), set this to provide some context for why it occurred. + /// + public void SetDisconnectReason( DisconnectReasonType reason) + { + //using an explicit setter here rather than the auto-property, to make the code locations where disconnect information is set more obvious. + Reason = reason; + } + + /// + /// The reason why a disconnect occurred, or Undefined if not set. + /// + public DisconnectReasonType Reason { get; private set; } = DisconnectReasonType.Undefined; + + /// + /// Clear the DisconnectReason, returning it to Undefined. + /// + public void Clear() + { + Reason = DisconnectReasonType.Undefined; + } + + /// + /// Has a TransitionReason already be set? (The TransitionReason provides context for why someone transition back to the MainMenu, and is a one-use item + /// that is unset as soon as it is read). + /// + public bool HasTransitionReason => Reason != DisconnectReasonType.Undefined; + } +} diff --git a/Assets/BossRoom/Scripts/Client/Net/DisconnectReason.cs.meta b/Assets/BossRoom/Scripts/Client/Net/DisconnectReason.cs.meta new file mode 100644 index 000000000..fb7d32177 --- /dev/null +++ b/Assets/BossRoom/Scripts/Client/Net/DisconnectReason.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: c92998344b3ecfa4da078bd59ebd469e +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/BossRoom/Scripts/Client/UI/MainMenuUI.cs b/Assets/BossRoom/Scripts/Client/UI/MainMenuUI.cs index b36092c47..b8fddfbaa 100644 --- a/Assets/BossRoom/Scripts/Client/UI/MainMenuUI.cs +++ b/Assets/BossRoom/Scripts/Client/UI/MainMenuUI.cs @@ -34,15 +34,9 @@ void Start() m_ClientNetPortal.NetworkTimedOut += OnNetworkTimeout; m_ClientNetPortal.ConnectFinished += OnConnectFinished; - var stateGO = GameObject.FindGameObjectWithTag("ActiveState"); - var mainMenuState = stateGO != null ? stateGO.GetComponent() : null; - if( mainMenuState != null ) + if (m_ClientNetPortal.DisconnectReason.Reason == DisconnectReasonType.Disconnect ) { - var transitionReason = mainMenuState.ReadAndUnsetTransitionReason(); - if( transitionReason == ClientMainMenuState.TransitionReason.Disconnect ) - { - m_ResponsePopup.SetupNotifierDisplay("Disconnected From Host", "The connection to the Host was lost", false, true ); - } + m_ResponsePopup.SetupNotifierDisplay("Disconnected From Host", "The connection to the Host was lost", false, true ); } } diff --git a/ProjectSettings/TagManager.asset b/ProjectSettings/TagManager.asset index b243daabb..f599ad253 100644 --- a/ProjectSettings/TagManager.asset +++ b/ProjectSettings/TagManager.asset @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:20c968555c901eab94e878b1e5d0131e6a749b2c73203b2a1a16f6ac22733ee8 -size 565 +oid sha256:bd98f6f2c43732be288a6ea3709f3f35b2cb5a720c64f605b322798373557c8b +size 549 From 6681c1f38d8631cee38934cfbdcf2d95ca777f38 Mon Sep 17 00:00:00 2001 From: David Woodruff Date: Tue, 20 Apr 2021 20:58:53 -0400 Subject: [PATCH 4/4] moving disconnect reset to a better place. Now it will happen even if a client decides to become a host, and regardless of whether starting as a client or relay client. --- Assets/BossRoom/Scripts/Client/Net/ClientGameNetPortal.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Assets/BossRoom/Scripts/Client/Net/ClientGameNetPortal.cs b/Assets/BossRoom/Scripts/Client/Net/ClientGameNetPortal.cs index e930472cc..c88604a00 100644 --- a/Assets/BossRoom/Scripts/Client/Net/ClientGameNetPortal.cs +++ b/Assets/BossRoom/Scripts/Client/Net/ClientGameNetPortal.cs @@ -47,6 +47,8 @@ void Start() private void NetworkStart() { + DisconnectReason.Clear(); + if (!m_Portal.NetManager.IsClient) { enabled = false; @@ -132,8 +134,6 @@ private void OnDisconnectOrTimeout(ulong clientID) /// The port of the host to connect to. public static void StartClient(GameNetPortal portal, string ipaddress, int port) { - portal.GetComponent().DisconnectReason.Clear(); - var chosenTransport = NetworkManager.Singleton.gameObject.GetComponent().IpHostTransport; NetworkManager.Singleton.NetworkConfig.NetworkTransport = chosenTransport;