diff --git a/Assets/Scripts/Environment/Pitfall.cs b/Assets/Scripts/Environment/Pitfall.cs index ab1705a..f518807 100644 --- a/Assets/Scripts/Environment/Pitfall.cs +++ b/Assets/Scripts/Environment/Pitfall.cs @@ -1,7 +1,9 @@ using MLAPI; +using MLAPI.Exceptions; using MLAPI.Messaging; using System.Collections; using System.Collections.Generic; +using System.Linq; using UnityEngine; public class Pitfall : NetworkBehaviour @@ -35,8 +37,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) { @@ -45,46 +45,67 @@ 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.LogError("Spawn State Exception Exception:"); + Debug.LogError(e); + 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; + _runner.GetComponent().SpawnAsPlayerObject(clientID, null, true); + + // Turn on camera if the player is the host + if (NetworkManager.Singleton.LocalClientId == clientID) { - TargetClientIds = new ulong[] { 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; + + _runner.GetComponentInChildren().enabled = true; } - }; - // Spawn via RPC on the server - SpawnPlayerClientRpc(clientID, clientRpcParams); + else + { + // Spawn via RPC on the server + string itemsAsString = string.Join(",", playerData.pInv.NetworkItemList); + StartCoroutine(SpawnClient(clientID, itemsAsString)); + } + } } } } } + // The client respawning needs a slight delay to allow for the spawn to properly sync up + IEnumerator SpawnClient(ulong clientID, string itemsAsString) + { + yield return new WaitForSecondsRealtime(1f); + + ClientRpcParams clientRpcParams = new ClientRpcParams + { + Send = new ClientRpcSendParams + { + TargetClientIds = new ulong[] { clientID } + } + }; + + 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"); @@ -93,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/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/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]); } } - - }