From ade428ef8a6765a11f99a45e2f9188ad02581d74 Mon Sep 17 00:00:00 2001 From: Julia Butenhoff Date: Tue, 18 Jan 2022 11:46:26 -0600 Subject: [PATCH 1/3] Fixed Pitfall Respawning On Clients --- Assets/Scripts/Environment/Pitfall.cs | 83 +++++++++++++++++---------- UserSettings/EditorUserSettings.asset | 2 +- 2 files changed, 55 insertions(+), 30 deletions(-) diff --git a/Assets/Scripts/Environment/Pitfall.cs b/Assets/Scripts/Environment/Pitfall.cs index ab1705a..5f2b7ac 100644 --- a/Assets/Scripts/Environment/Pitfall.cs +++ b/Assets/Scripts/Environment/Pitfall.cs @@ -1,4 +1,5 @@ using MLAPI; +using MLAPI.Exceptions; using MLAPI.Messaging; using System.Collections; using System.Collections.Generic; @@ -45,43 +46,62 @@ public class Pitfall : NetworkBehaviour // Player found // Despawn them - character.GetComponent().Despawn(true); - } - } - - // Spawn the player - if (ServerGameNetPortal.Instance.clientIdToGuid.TryGetValue(clientID, out string clientGuid)) - { - if (ServerGameNetPortal.Instance.clientData.TryGetValue(clientGuid, out PlayerData playerData)) - { - // Spawn as player - _runner = Instantiate(runnerPrefab, RespawnPoint, Quaternion.Euler(0, -90, 0)).gameObject; - //Recreate Inventory - _runner.GetComponentInChildren().UpdateEquips(playerData.pInv.NetworkItemList, this.gameObject.GetComponent().ItemDict); - _runner.GetComponent().SpawnAsPlayerObject(clientID, null, true); - - // Turn on camera if the player is the host - if (NetworkManager.Singleton.LocalClientId == clientID) { - GameHandler.FindGameObjectInChildWithTag(_runner, "PlayerCam").GetComponent().enabled = true; - GameHandler.FindGameObjectInChildWithTag(_runner, "PlayerCam").GetComponent().enabled = true; - GameHandler.FindGameObjectInChildWithTag(_runner, "PlayerCam").GetComponent().enabled = true; - - _runner.GetComponentInChildren().enabled = true; - } else { - ClientRpcParams clientRpcParams = new ClientRpcParams + try + { + character.GetComponent().Despawn(true); + } catch (SpawnStateException e) { + Debug.Log("Exception"); + return; + } + + // Spawn the player + if (ServerGameNetPortal.Instance.clientIdToGuid.TryGetValue(clientID, out string clientGuid)) + { + if (ServerGameNetPortal.Instance.clientData.TryGetValue(clientGuid, out PlayerData playerData)) { - Send = new ClientRpcSendParams + // Spawn as player + _runner = Instantiate(runnerPrefab, RespawnPoint, Quaternion.Euler(0, -90, 0)).gameObject; + //Recreate Inventory + // FOLLOWING LINE WILL NEED TO BE UPDATED SINCE THIS WILL ONLY WORK FOR THE HOST AND NOT THE CONNECTED CLIENTS + _runner.GetComponentInChildren().UpdateEquips(playerData.pInv.NetworkItemList, this.gameObject.GetComponent().ItemDict); + _runner.GetComponent().SpawnAsPlayerObject(clientID, null, true); + + // Turn on camera if the player is the host + if (NetworkManager.Singleton.LocalClientId == clientID) { - TargetClientIds = new ulong[] { clientID } + GameHandler.FindGameObjectInChildWithTag(_runner, "PlayerCam").GetComponent().enabled = true; + GameHandler.FindGameObjectInChildWithTag(_runner, "PlayerCam").GetComponent().enabled = true; + GameHandler.FindGameObjectInChildWithTag(_runner, "PlayerCam").GetComponent().enabled = true; + + _runner.GetComponentInChildren().enabled = true; } - }; - // Spawn via RPC on the server - SpawnPlayerClientRpc(clientID, clientRpcParams); + else + { + // Spawn via RPC on the server + StartCoroutine(SpawnClient(clientID)); + } + } } } } } + // The client respawning needs a slight delay to allow for the spawn to properly sync up + IEnumerator SpawnClient(ulong clientID) + { + yield return new WaitForSecondsRealtime(1f); + + ClientRpcParams clientRpcParams = new ClientRpcParams + { + Send = new ClientRpcSendParams + { + TargetClientIds = new ulong[] { clientID } + } + }; + + SpawnPlayerClientRpc(clientID, clientRpcParams); + } + // Spawn in each player [ClientRpc] public void SpawnPlayerClientRpc(ulong clientId, ClientRpcParams clientRpcParams = default) @@ -93,12 +113,17 @@ public class Pitfall : NetworkBehaviour { if (character.GetComponent().OwnerClientId == clientId) { + Debug.LogError("Found"); GameHandler.FindGameObjectInChildWithTag(character, "PlayerCam").GetComponent().enabled = true; GameHandler.FindGameObjectInChildWithTag(character, "PlayerCam").GetComponent().enabled = true; GameHandler.FindGameObjectInChildWithTag(character, "PlayerCam").GetComponent().enabled = true; character.GetComponentInChildren().enabled = true; } + else + { + Debug.LogError("Failed to find"); + } } } } diff --git a/UserSettings/EditorUserSettings.asset b/UserSettings/EditorUserSettings.asset index 07f941b..e97a416 100644 --- a/UserSettings/EditorUserSettings.asset +++ b/UserSettings/EditorUserSettings.asset @@ -33,7 +33,7 @@ EditorUserSettings: value: 22424703114646680e0b0227036c6f02131b172b282d347e38271427fb flags: 0 RecentlyUsedScenePath-9: - value: 22424703114646680e0b0227036c78111b125507233d28242c20137df7ee3d2cfb + value: 22424703114646680e0b0227036c6f02131b172b282d347e38271427fb flags: 0 UnityRemoteCompression: value: 337f73 From 8d81c92115a52ab904dec8362bd716881d1a82d0 Mon Sep 17 00:00:00 2001 From: Julia Butenhoff Date: Wed, 19 Jan 2022 16:36:10 -0600 Subject: [PATCH 2/3] Fixed Runner Spectating King Bug - Fixed a bug where a runner would spectate the king if the host and a client are both runners and the client finished the race before the host did --- Assets/Scripts/Environment/Pitfall.cs | 10 ++-------- Assets/Scripts/Game/EndCollider.cs | 3 +-- UserSettings/EditorUserSettings.asset | 2 +- 3 files changed, 4 insertions(+), 11 deletions(-) diff --git a/Assets/Scripts/Environment/Pitfall.cs b/Assets/Scripts/Environment/Pitfall.cs index 5f2b7ac..43f0341 100644 --- a/Assets/Scripts/Environment/Pitfall.cs +++ b/Assets/Scripts/Environment/Pitfall.cs @@ -36,8 +36,6 @@ public class Pitfall : NetworkBehaviour // Get all players in the scene GameObject[] playableCharacters = GameObject.FindGameObjectsWithTag("Player"); - Debug.LogError("# of players: " + playableCharacters.Length); - // Find our player first foreach (GameObject character in playableCharacters) { @@ -50,7 +48,8 @@ public class Pitfall : NetworkBehaviour { character.GetComponent().Despawn(true); } catch (SpawnStateException e) { - Debug.Log("Exception"); + Debug.LogError("Spawn State Exception Exception:"); + Debug.LogError(e); return; } @@ -113,17 +112,12 @@ public class Pitfall : NetworkBehaviour { if (character.GetComponent().OwnerClientId == clientId) { - Debug.LogError("Found"); GameHandler.FindGameObjectInChildWithTag(character, "PlayerCam").GetComponent().enabled = true; GameHandler.FindGameObjectInChildWithTag(character, "PlayerCam").GetComponent().enabled = true; GameHandler.FindGameObjectInChildWithTag(character, "PlayerCam").GetComponent().enabled = true; character.GetComponentInChildren().enabled = true; } - else - { - Debug.LogError("Failed to find"); - } } } } diff --git a/Assets/Scripts/Game/EndCollider.cs b/Assets/Scripts/Game/EndCollider.cs index e41e938..502a33e 100644 --- a/Assets/Scripts/Game/EndCollider.cs +++ b/Assets/Scripts/Game/EndCollider.cs @@ -39,7 +39,6 @@ public class EndCollider : NetworkBehaviour { } } - //todo: Check if all runners are finished bool allFinished = true; foreach (PlayerData pData in ServerGameNetPortal.Instance.clientData.Values) { // Make sure we don't check the king, since the value of Finished will always be false @@ -60,7 +59,7 @@ public class EndCollider : NetworkBehaviour { // Make sure we find the characters that aren't the one that just finished (subsequently calling the rpc) if (character.GetComponent().OwnerClientId != serverRpcParams.Receive.SenderClientId) { // Then grab their GUID - if (ServerGameNetPortal.Instance.clientIdToGuid.TryGetValue(serverRpcParams.Receive.SenderClientId, out string clientGuid)) { + if (ServerGameNetPortal.Instance.clientIdToGuid.TryGetValue(character.GetComponent().OwnerClientId, out string clientGuid)) { // To verify they aren't the king if (ServerGameNetPortal.Instance.clientData[clientGuid].IsKing != true) { // Then call a client rpc to the finished player to enable the camera locally diff --git a/UserSettings/EditorUserSettings.asset b/UserSettings/EditorUserSettings.asset index e97a416..07f941b 100644 --- a/UserSettings/EditorUserSettings.asset +++ b/UserSettings/EditorUserSettings.asset @@ -33,7 +33,7 @@ EditorUserSettings: value: 22424703114646680e0b0227036c6f02131b172b282d347e38271427fb flags: 0 RecentlyUsedScenePath-9: - value: 22424703114646680e0b0227036c6f02131b172b282d347e38271427fb + value: 22424703114646680e0b0227036c78111b125507233d28242c20137df7ee3d2cfb flags: 0 UnityRemoteCompression: value: 337f73 From c1d51f4148d062604668f31e015963f6974efdc6 Mon Sep 17 00:00:00 2001 From: Julia Butenhoff Date: Wed, 19 Jan 2022 17:28:12 -0600 Subject: [PATCH 3/3] Fixed Items Not Apply to Clients Bug - Fixed a bug in which clients were not spawned in with their items despite selecting them in the lobby. Also applied this fix to the respawn method for the pitfalls --- Assets/Scripts/Environment/Pitfall.cs | 20 +++++---- Assets/Scripts/Network/Game/SpawnManager.cs | 42 ++++++++++++++++++- Assets/Scripts/Network/PlayerData.cs | 2 +- .../Scripts/PlayerScripts/PlayerInventory.cs | 2 - 4 files changed, 54 insertions(+), 12 deletions(-) diff --git a/Assets/Scripts/Environment/Pitfall.cs b/Assets/Scripts/Environment/Pitfall.cs index 43f0341..f518807 100644 --- a/Assets/Scripts/Environment/Pitfall.cs +++ b/Assets/Scripts/Environment/Pitfall.cs @@ -3,6 +3,7 @@ using MLAPI.Exceptions; using MLAPI.Messaging; using System.Collections; using System.Collections.Generic; +using System.Linq; using UnityEngine; public class Pitfall : NetworkBehaviour @@ -60,14 +61,14 @@ public class Pitfall : NetworkBehaviour { // Spawn as player _runner = Instantiate(runnerPrefab, RespawnPoint, Quaternion.Euler(0, -90, 0)).gameObject; - //Recreate Inventory - // FOLLOWING LINE WILL NEED TO BE UPDATED SINCE THIS WILL ONLY WORK FOR THE HOST AND NOT THE CONNECTED CLIENTS - _runner.GetComponentInChildren().UpdateEquips(playerData.pInv.NetworkItemList, this.gameObject.GetComponent().ItemDict); _runner.GetComponent().SpawnAsPlayerObject(clientID, null, true); // Turn on camera if the player is the host if (NetworkManager.Singleton.LocalClientId == clientID) { + // Recreate Inventory (host) + _runner.GetComponentInChildren().UpdateEquips(playerData.pInv.NetworkItemList, this.gameObject.GetComponent().ItemDict); + GameHandler.FindGameObjectInChildWithTag(_runner, "PlayerCam").GetComponent().enabled = true; GameHandler.FindGameObjectInChildWithTag(_runner, "PlayerCam").GetComponent().enabled = true; GameHandler.FindGameObjectInChildWithTag(_runner, "PlayerCam").GetComponent().enabled = true; @@ -77,7 +78,8 @@ public class Pitfall : NetworkBehaviour else { // Spawn via RPC on the server - StartCoroutine(SpawnClient(clientID)); + string itemsAsString = string.Join(",", playerData.pInv.NetworkItemList); + StartCoroutine(SpawnClient(clientID, itemsAsString)); } } } @@ -86,7 +88,7 @@ public class Pitfall : NetworkBehaviour } // The client respawning needs a slight delay to allow for the spawn to properly sync up - IEnumerator SpawnClient(ulong clientID) + IEnumerator SpawnClient(ulong clientID, string itemsAsString) { yield return new WaitForSecondsRealtime(1f); @@ -98,12 +100,12 @@ public class Pitfall : NetworkBehaviour } }; - SpawnPlayerClientRpc(clientID, clientRpcParams); + SpawnPlayerClientRpc(clientID, itemsAsString, clientRpcParams); } // Spawn in each player [ClientRpc] - public void SpawnPlayerClientRpc(ulong clientId, ClientRpcParams clientRpcParams = default) + public void SpawnPlayerClientRpc(ulong clientId, string itemsAsString, ClientRpcParams clientRpcParams = default) { GameObject[] playableCharacters = GameObject.FindGameObjectsWithTag("Player"); @@ -112,6 +114,10 @@ public class Pitfall : NetworkBehaviour { if (character.GetComponent().OwnerClientId == clientId) { + // Rebuild inventory + List itemList = itemsAsString.Split(',').ToList(); + character.GetComponentInChildren().UpdateEquips(itemList, this.gameObject.GetComponent().ItemDict); + GameHandler.FindGameObjectInChildWithTag(character, "PlayerCam").GetComponent().enabled = true; GameHandler.FindGameObjectInChildWithTag(character, "PlayerCam").GetComponent().enabled = true; GameHandler.FindGameObjectInChildWithTag(character, "PlayerCam").GetComponent().enabled = true; diff --git a/Assets/Scripts/Network/Game/SpawnManager.cs b/Assets/Scripts/Network/Game/SpawnManager.cs index 06839a9..03ae245 100644 --- a/Assets/Scripts/Network/Game/SpawnManager.cs +++ b/Assets/Scripts/Network/Game/SpawnManager.cs @@ -1,3 +1,6 @@ +using System.Collections; +using System.Collections.Generic; +using System.Linq; using MLAPI; using MLAPI.Messaging; using UnityEngine; @@ -70,14 +73,49 @@ public class SpawnManager : NetworkBehaviour { } else { // Spawn as player _runner = Instantiate(runnerPrefab, runnersSpawnPoints[runnersSpawned], Quaternion.Euler(0, -90, 0)).gameObject; - //Recreate Inventory - _runner.GetComponentInChildren().UpdateEquips(playerData.pInv.NetworkItemList, this.gameObject.GetComponent().ItemDict); _runner.GetComponent().SpawnAsPlayerObject(clientId, null, true); // Increment runners runnersSpawned++; + + // Tell the client to apply the inventory to its player + string itemsAsString = string.Join(",", playerData.pInv.NetworkItemList); + StartCoroutine(ApplyInventoryToClient(clientId, itemsAsString)); } } } } + + // Give a slight delay to allow spawning to complete + IEnumerator ApplyInventoryToClient(ulong clientID, string itemsAsString) + { + yield return new WaitForSecondsRealtime(1f); + + ClientRpcParams clientRpcParams = new ClientRpcParams + { + Send = new ClientRpcSendParams + { + TargetClientIds = new ulong[] { clientID } + } + }; + + ApplyInventoryClientRPC(clientID, itemsAsString, clientRpcParams); + } + + [ClientRpc] + private void ApplyInventoryClientRPC(ulong clientID, string itemsAsString, ClientRpcParams clientRpcParams = default) { + + + GameObject[] playableCharacters = GameObject.FindGameObjectsWithTag("Player"); + + // Loop over the characters + foreach (GameObject character in playableCharacters) { + // Find the local player + if (character.GetComponent().OwnerClientId == clientID) { + List itemList = itemsAsString.Split(',').ToList(); + + character.GetComponentInChildren().UpdateEquips(itemList, this.gameObject.GetComponent().ItemDict); + } + } + } } diff --git a/Assets/Scripts/Network/PlayerData.cs b/Assets/Scripts/Network/PlayerData.cs index 94b3940..4382284 100644 --- a/Assets/Scripts/Network/PlayerData.cs +++ b/Assets/Scripts/Network/PlayerData.cs @@ -3,7 +3,7 @@ public struct PlayerData { public string PlayerName { get; private set; } public ulong ClientId { get; private set; } public bool IsKing { get; set; } - public PlayerInventory pInv{get; set;} + public PlayerInventory pInv { get; set; } public bool Finished { get; set; } diff --git a/Assets/Scripts/PlayerScripts/PlayerInventory.cs b/Assets/Scripts/PlayerScripts/PlayerInventory.cs index 7e3ec80..67e3a5f 100644 --- a/Assets/Scripts/PlayerScripts/PlayerInventory.cs +++ b/Assets/Scripts/PlayerScripts/PlayerInventory.cs @@ -72,6 +72,4 @@ public class PlayerInventory : NetworkBehaviour AddItem(allItems[itemName]); } } - - }