From bbfa85343b96fb4afafb505c5705856c2ef4b51a Mon Sep 17 00:00:00 2001 From: Ali Sharoz Date: Wed, 22 Jan 2025 22:43:25 +0500 Subject: [PATCH] Timer Bug and Plaform Bug Fixed --- Assets/Scenes/BossRoom.unity | 72 ++--- Assets/Scripts/Gameplay/Platform.cs | 195 ++++++++++++-- Assets/Scripts/Gameplay/PlatformManager.cs | 298 ++++++++++++++++----- Assets/SynchronizedTimer.cs | 55 ++-- Assets/TimerScript.cs | 21 +- 5 files changed, 483 insertions(+), 158 deletions(-) diff --git a/Assets/Scenes/BossRoom.unity b/Assets/Scenes/BossRoom.unity index 3456659..3bd1621 100644 --- a/Assets/Scenes/BossRoom.unity +++ b/Assets/Scenes/BossRoom.unity @@ -773,6 +773,10 @@ PrefabInstance: serializedVersion: 3 m_TransformParent: {fileID: 0} m_Modifications: + - target: {fileID: 109254, guid: 67117722a812a2e46ab8cb8eafbf5f5e, type: 3} + propertyPath: m_IsActive + value: 0 + objectReference: {fileID: 0} - target: {fileID: 132536, guid: 67117722a812a2e46ab8cb8eafbf5f5e, type: 3} propertyPath: m_Name value: IngameDebugConsole @@ -797,6 +801,10 @@ PrefabInstance: propertyPath: m_AnchorMax.y value: 0 objectReference: {fileID: 0} + - target: {fileID: 22426080, guid: 67117722a812a2e46ab8cb8eafbf5f5e, type: 3} + propertyPath: m_AnchorMin.y + value: 0 + objectReference: {fileID: 0} - target: {fileID: 22428984, guid: 67117722a812a2e46ab8cb8eafbf5f5e, type: 3} propertyPath: m_AnchorMax.y value: 0 @@ -9662,11 +9670,11 @@ PrefabInstance: objectReference: {fileID: 0} - target: {fileID: 1676734515771252668, guid: 0193228de87741d40a42e561901c9083, type: 3} propertyPath: m_LocalRotation.y - value: 0.28987613 + value: 0.28987607 objectReference: {fileID: 0} - target: {fileID: 1676734515771252668, guid: 0193228de87741d40a42e561901c9083, type: 3} propertyPath: m_LocalRotation.z - value: -0.18152039 + value: -0.18152031 objectReference: {fileID: 0} - target: {fileID: 1676734516302391364, guid: 0193228de87741d40a42e561901c9083, type: 3} propertyPath: m_UpdateMethod @@ -9694,19 +9702,19 @@ PrefabInstance: objectReference: {fileID: 0} - target: {fileID: 1676734516695783279, guid: 0193228de87741d40a42e561901c9083, type: 3} propertyPath: m_LocalRotation.w - value: 0.7900695 + value: 0.79006946 objectReference: {fileID: 0} - target: {fileID: 1676734516695783279, guid: 0193228de87741d40a42e561901c9083, type: 3} propertyPath: m_LocalRotation.x - value: 0.5087362 + value: 0.50873625 objectReference: {fileID: 0} - target: {fileID: 1676734516695783279, guid: 0193228de87741d40a42e561901c9083, type: 3} propertyPath: m_LocalRotation.y - value: 0.2875617 + value: 0.2875618 objectReference: {fileID: 0} - target: {fileID: 1676734516695783279, guid: 0193228de87741d40a42e561901c9083, type: 3} propertyPath: m_LocalRotation.z - value: -0.18516475 + value: -0.18516485 objectReference: {fileID: 0} - target: {fileID: 1676734516724634599, guid: 0193228de87741d40a42e561901c9083, type: 3} propertyPath: m_LocalPosition.y @@ -9718,7 +9726,7 @@ PrefabInstance: objectReference: {fileID: 0} - target: {fileID: 1676734516724634599, guid: 0193228de87741d40a42e561901c9083, type: 3} propertyPath: m_LocalRotation.w - value: 0.8027669 + value: 0.80276686 objectReference: {fileID: 0} - target: {fileID: 1676734516724634599, guid: 0193228de87741d40a42e561901c9083, type: 3} propertyPath: m_LocalRotation.x @@ -9726,11 +9734,11 @@ PrefabInstance: objectReference: {fileID: 0} - target: {fileID: 1676734516724634599, guid: 0193228de87741d40a42e561901c9083, type: 3} propertyPath: m_LocalRotation.y - value: 0.29218328 + value: 0.2921833 objectReference: {fileID: 0} - target: {fileID: 1676734516724634599, guid: 0193228de87741d40a42e561901c9083, type: 3} propertyPath: m_LocalRotation.z - value: -0.17778282 + value: -0.17778286 objectReference: {fileID: 0} - target: {fileID: 1676734516866984540, guid: 0193228de87741d40a42e561901c9083, type: 3} propertyPath: m_VerticalDamping @@ -9959,19 +9967,19 @@ PrefabInstance: objectReference: {fileID: 0} - target: {fileID: 203267159508449512, guid: 36b3ee75677a1544191c0ddaaadd8140, type: 3} propertyPath: m_LocalRotation.w - value: 0.7900696 + value: 0.79006934 objectReference: {fileID: 0} - target: {fileID: 203267159508449512, guid: 36b3ee75677a1544191c0ddaaadd8140, type: 3} propertyPath: m_LocalRotation.x - value: 0.50873613 + value: 0.5087363 objectReference: {fileID: 0} - target: {fileID: 203267159508449512, guid: 36b3ee75677a1544191c0ddaaadd8140, type: 3} propertyPath: m_LocalRotation.y - value: 0.2875617 + value: 0.28756183 objectReference: {fileID: 0} - target: {fileID: 203267159508449512, guid: 36b3ee75677a1544191c0ddaaadd8140, type: 3} propertyPath: m_LocalRotation.z - value: -0.18516473 + value: -0.18516491 objectReference: {fileID: 0} - target: {fileID: 203267159508449512, guid: 36b3ee75677a1544191c0ddaaadd8140, type: 3} propertyPath: m_LocalEulerAnglesHint.x @@ -15032,8 +15040,8 @@ Transform: m_GameObject: {fileID: 260583547567553435} serializedVersion: 2 m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} - m_LocalPosition: {x: 27.65, y: 0.52599907, z: -7.859985} - m_LocalScale: {x: -1, y: 1, z: 1} + m_LocalPosition: {x: 32.92, y: 0.53, z: -7.650648} + m_LocalScale: {x: 1, y: 1, z: 1} m_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 1932532498} @@ -58498,8 +58506,8 @@ Transform: m_GameObject: {fileID: 1304717044120688010} serializedVersion: 2 m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} - m_LocalPosition: {x: 27.65, y: 0.52599907, z: 12.390014} - m_LocalScale: {x: -1, y: 1, z: 1} + m_LocalPosition: {x: 32.65, y: 0.52599907, z: 12.390014} + m_LocalScale: {x: 1, y: 1, z: 1} m_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 1932532498} @@ -70567,7 +70575,7 @@ Transform: serializedVersion: 2 m_LocalRotation: {x: -0, y: -0.70710677, z: -0, w: 0.7071068} m_LocalPosition: {x: 22.75, y: -19.25, z: -336.5} - m_LocalScale: {x: -1, y: 1, z: 1} + m_LocalScale: {x: 1, y: 1, z: 1} m_ConstrainProportionsScale: 0 m_Children: - {fileID: 1960577389555045427} @@ -72444,8 +72452,8 @@ Transform: m_GameObject: {fileID: 2121072211875613479} serializedVersion: 2 m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} - m_LocalPosition: {x: 32.65, y: 0.52599907, z: -7.859985} - m_LocalScale: {x: -1, y: 1, z: 1} + m_LocalPosition: {x: 37.65, y: 0.52599907, z: -7.859985} + m_LocalScale: {x: 1, y: 1, z: 1} m_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 1932532498} @@ -160806,8 +160814,8 @@ Transform: m_GameObject: {fileID: 5052075383141419431} serializedVersion: 2 m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} - m_LocalPosition: {x: 37.65, y: 0.52599907, z: -2.8599854} - m_LocalScale: {x: -1, y: 1, z: 1} + m_LocalPosition: {x: 42.65, y: 0.52599907, z: -2.8599854} + m_LocalScale: {x: 1, y: 1, z: 1} m_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 1932532498} @@ -227311,8 +227319,8 @@ Transform: m_GameObject: {fileID: 7499118337776080084} serializedVersion: 2 m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} - m_LocalPosition: {x: 32.65, y: 0.52599907, z: 7.3900146} - m_LocalScale: {x: -1, y: 1, z: 1} + m_LocalPosition: {x: 37.65, y: 0.52599907, z: 7.3900146} + m_LocalScale: {x: 1, y: 1, z: 1} m_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 1932532498} @@ -228360,8 +228368,8 @@ Transform: m_GameObject: {fileID: 7590670908784232642} serializedVersion: 2 m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} - m_LocalPosition: {x: 27.65, y: 0.52599907, z: 7.3900146} - m_LocalScale: {x: -1, y: 1, z: 1} + m_LocalPosition: {x: 32.65, y: 0.52599907, z: 7.3900146} + m_LocalScale: {x: 1, y: 1, z: 1} m_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 1932532498} @@ -262429,8 +262437,8 @@ Transform: m_GameObject: {fileID: 8544586393924102526} serializedVersion: 2 m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} - m_LocalPosition: {x: 22.65, y: 0.52599907, z: 27.140013} - m_LocalScale: {x: -1, y: 1, z: 1} + m_LocalPosition: {x: 27.65, y: 0.52599907, z: 27.140013} + m_LocalScale: {x: 1, y: 1, z: 1} m_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 1932532498} @@ -262946,8 +262954,8 @@ Transform: m_GameObject: {fileID: 8577154754468567942} serializedVersion: 2 m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} - m_LocalPosition: {x: 17.65, y: 0.52599907, z: 27.140013} - m_LocalScale: {x: -1, y: 1, z: 1} + m_LocalPosition: {x: 22.65, y: 0.52599907, z: 27.140013} + m_LocalScale: {x: 1, y: 1, z: 1} m_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 1932532498} @@ -281962,8 +281970,8 @@ Transform: m_GameObject: {fileID: 9182889245508031729} serializedVersion: 2 m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} - m_LocalPosition: {x: 32.65, y: 0.52599907, z: -2.8599854} - m_LocalScale: {x: -1, y: 1, z: 1} + m_LocalPosition: {x: 37.65, y: 0.52599907, z: -2.8599854} + m_LocalScale: {x: 1, y: 1, z: 1} m_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 1932532498} diff --git a/Assets/Scripts/Gameplay/Platform.cs b/Assets/Scripts/Gameplay/Platform.cs index e55b68e..f669df6 100644 --- a/Assets/Scripts/Gameplay/Platform.cs +++ b/Assets/Scripts/Gameplay/Platform.cs @@ -2,7 +2,6 @@ using Unity.BossRoom.Gameplay.GameplayObjects.Character; using Unity.Netcode; using UnityEngine; using DG.Tweening; -using Unity.Netcode.Components; namespace Unity.Multiplayer.Samples.BossRoom { @@ -15,67 +14,96 @@ namespace Unity.Multiplayer.Samples.BossRoom private NetworkVariable occupierId = new NetworkVariable(0, NetworkVariableReadPermission.Everyone, NetworkVariableWritePermission.Server); private Collider platformCollider; private Animator animator; + private void Awake() { platformCollider = GetComponent(); - if (!platformCollider.isTrigger) - platformCollider.isTrigger = true; + platformCollider.isTrigger = true; animator = GetComponent(); } + private void Start() { - Invoke(nameof(ColliderEnabler),2); + if (IsServer) + { + Invoke(nameof(EnableCollider), 2); // Delay collider enabling for server + } } + public void AssignID(int id) { - if (IsServer) PlatformID.Value = id; + if (IsServer) + { + PlatformID.Value = id; + } } - void ColliderEnabler() + + private void EnableCollider() { platformCollider.enabled = true; } - public void StartRotation() => transform.DOLocalRotate(Vector3.up, 120).SetSpeedBased(true).SetId(PlatformID).SetLoops(-1, LoopType.Incremental); - private void PauseRotation() => DOTween.Pause(PlatformID); - private void ResumeRotation() => DOTween.Play(PlatformID); + public void StartRotation() + { + transform.DOLocalRotate(Vector3.up, 120).SetSpeedBased(true).SetId(PlatformID).SetLoops(-1, LoopType.Incremental); + } + + private void PauseRotation() + { + DOTween.Pause(PlatformID); + } + + private void ResumeRotation() + { + DOTween.Play(PlatformID); + } public void Pause() { - if (IsOwner) + if (IsServer) { animator.speed = 0f; - PauseServerRpc(); + PauseClientRpc(); } } public void Resume() { - if (IsOwner) + if (IsServer) { animator.speed = 1f; - ResumeServerRpc(); + ResumeClientRpc(); } } - [ServerRpc] - private void PauseServerRpc() => PauseClientRpc(); [ClientRpc] - private void PauseClientRpc() => animator.speed = 0f; + private void PauseClientRpc() + { + animator.speed = 0f; + } - [ServerRpc] - private void ResumeServerRpc() => ResumeClientRpc(); [ClientRpc] - private void ResumeClientRpc() => animator.speed = 1f; + private void ResumeClientRpc() + { + animator.speed = 1f; + } public void Occupy(ServerCharacter player) { - if (!IsServer || IsOccupied) return; + if (!IsServer || IsOccupied) + { + return; + } + Pause(); bool giveScore = player.PreviousPlatformId != PlatformID.Value; int score = (player.TargetPlatformId == PlatformID.Value) ? 10 : 20; - if (giveScore) ScoreManager.Instance.AddPlayerScore(player.OwnerClientId, score); + if (giveScore) + { + ScoreManager.Instance.AddPlayerScore(player.OwnerClientId, score); + } IsOccupied = true; occupierId.Value = player.OwnerClientId; @@ -84,7 +112,10 @@ namespace Unity.Multiplayer.Samples.BossRoom public void Vacate(ServerCharacter player) { - if (!IsServer || !IsOccupied || occupierId.Value != player.OwnerClientId) return; + if (!IsServer || !IsOccupied || occupierId.Value != player.OwnerClientId) + { + return; + } Resume(); IsOccupied = false; @@ -95,15 +126,133 @@ namespace Unity.Multiplayer.Samples.BossRoom private void OnTriggerEnter(Collider other) { if (IsServer && other.TryGetComponent(out var player) && !IsOccupied) + { Occupy(player); + } } private void OnTriggerExit(Collider other) { if (IsServer && other.TryGetComponent(out var player)) + { Vacate(player); + } } - public ulong GetOccupierId() => occupierId.Value; + public ulong GetOccupierId() + { + return occupierId.Value; + } } } + + +//using Unity.BossRoom.Gameplay.GameplayObjects.Character; +//using Unity.Netcode; +//using UnityEngine; +//using DG.Tweening; +//using Unity.Netcode.Components; + +//namespace Unity.Multiplayer.Samples.BossRoom +//{ +// [RequireComponent(typeof(Collider))] +// public class Platform : NetworkBehaviour +// { +// public NetworkVariable PlatformID = new NetworkVariable(0); +// public bool IsOccupied { get; private set; } + +// private NetworkVariable occupierId = new NetworkVariable(0, NetworkVariableReadPermission.Everyone, NetworkVariableWritePermission.Server); +// private Collider platformCollider; +// private Animator animator; +// private void Awake() +// { +// platformCollider = GetComponent(); +// if (!platformCollider.isTrigger) +// platformCollider.isTrigger = true; + +// animator = GetComponent(); +// } +// private void Start() +// { +// Invoke(nameof(ColliderEnabler),2); +// } +// public void AssignID(int id) +// { +// if (IsServer) PlatformID.Value = id; +// } +// void ColliderEnabler() +// { +// platformCollider.enabled = true; +// } +// public void StartRotation() => transform.DOLocalRotate(Vector3.up, 120).SetSpeedBased(true).SetId(PlatformID).SetLoops(-1, LoopType.Incremental); + +// private void PauseRotation() => DOTween.Pause(PlatformID); +// private void ResumeRotation() => DOTween.Play(PlatformID); + +// public void Pause() +// { +// if (IsOwner) +// { +// animator.speed = 0f; +// PauseServerRpc(); +// } +// } + +// public void Resume() +// { +// if (IsOwner) +// { +// animator.speed = 1f; +// ResumeServerRpc(); +// } +// } + +// [ServerRpc] +// private void PauseServerRpc() => PauseClientRpc(); +// [ClientRpc] +// private void PauseClientRpc() => animator.speed = 0f; + +// [ServerRpc] +// private void ResumeServerRpc() => ResumeClientRpc(); +// [ClientRpc] +// private void ResumeClientRpc() => animator.speed = 1f; + +// public void Occupy(ServerCharacter player) +// { +// if (!IsServer || IsOccupied) return; +// Pause(); +// bool giveScore = player.PreviousPlatformId != PlatformID.Value; +// int score = (player.TargetPlatformId == PlatformID.Value) ? 10 : 20; + +// if (giveScore) ScoreManager.Instance.AddPlayerScore(player.OwnerClientId, score); + +// IsOccupied = true; +// occupierId.Value = player.OwnerClientId; +// player.OnArrivalOnPlatform(PlatformID.Value); +// } + +// public void Vacate(ServerCharacter player) +// { +// if (!IsServer || !IsOccupied || occupierId.Value != player.OwnerClientId) return; + +// Resume(); +// IsOccupied = false; +// occupierId.Value = 0; +// player.OnLeavingPlatform(PlatformID.Value); +// } + +// private void OnTriggerEnter(Collider other) +// { +// if (IsServer && other.TryGetComponent(out var player) && !IsOccupied) +// Occupy(player); +// } + +// private void OnTriggerExit(Collider other) +// { +// if (IsServer && other.TryGetComponent(out var player)) +// Vacate(player); +// } + +// public ulong GetOccupierId() => occupierId.Value; +// } +//} diff --git a/Assets/Scripts/Gameplay/PlatformManager.cs b/Assets/Scripts/Gameplay/PlatformManager.cs index 5183d8c..9b25267 100644 --- a/Assets/Scripts/Gameplay/PlatformManager.cs +++ b/Assets/Scripts/Gameplay/PlatformManager.cs @@ -12,7 +12,6 @@ namespace Unity.Multiplayer.Samples.BossRoom public static PlatformManager Instance; public List m_Platforms; public int numberOfPlayers = 2; // Number of players (n) - public float planeRadius = 4f; // Radius of the circular plane private void Awake() { @@ -30,98 +29,91 @@ namespace Unity.Multiplayer.Samples.BossRoom { if (IsServer) { - m_Platforms = GetComponentsInChildren(true).ToList(); - for (int i = 0; i < m_Platforms.Count; i++) - { - m_Platforms[i].AssignID(i + 1); // Initialize platforms with unique IDs - } + InitializePlatforms(); StartCoroutine(DelayedServerSetup()); } - else - { - StartCoroutine(DelayedClientSetup()); // Delay to give time to load - } } /// - /// Coroutine to delay server-side setup. + /// Initializes platform list and assigns unique IDs. /// - private IEnumerator DelayedServerSetup() + private void InitializePlatforms() { - yield return new WaitForSeconds(0.5f); // Delay for 0.5 seconds - PlatformSelectionServerRpc(); // Call ServerRpc after delay + m_Platforms = GetComponentsInChildren(true).ToList(); + for (int i = 0; i < m_Platforms.Count; i++) + { + m_Platforms[i].AssignID(i + 1); // Assign unique IDs to platforms + } } /// - /// Coroutine to delay client-side setup. + /// Delayed server setup to allow other components to initialize. /// - private IEnumerator DelayedClientSetup() + private IEnumerator DelayedServerSetup() { yield return new WaitForSeconds(0.5f); - m_Platforms = GetComponentsInChildren(true).ToList(); // Populate client platform list - Debug.Log($"Client platform list initialized. Platform count: {m_Platforms.Count}"); + PlatformSelection(); } - [ServerRpc(RequireOwnership = false)] - private void PlatformSelectionServerRpc() + /// + /// Server-side logic to select and enable platforms based on player count. + /// + private void PlatformSelection() { - int platformsToSpawn = PlayerPrefs.GetInt("NumberOfLobbyPlayers") - 1; - m_Platforms.ForEach(platform => platform.gameObject.SetActive(false)); - Debug.Log("Disabled all platforms on the server."); + int platformsToSpawn = PlayerPrefs.GetInt("NumberOfLobbyPlayers",1) - 1; - if (platformsToSpawn > 0) + // Disable all platforms initially + foreach (var platform in m_Platforms) { - for (int i = 0; i < platformsToSpawn; i++) - { - m_Platforms[i].gameObject.SetActive(true); - Debug.Log($"Enabled platform with ID {m_Platforms[i].PlatformID.Value} on server."); - } + platform.gameObject.SetActive(false); + } + + // Enable required number of platforms + for (int i = 0; i < platformsToSpawn; i++) + { + Debug.Log(m_Platforms[i].gameObject.name + " is activated"); + m_Platforms[i].gameObject.SetActive(true); } - m_Platforms = m_Platforms.Where(platform => platform.gameObject.activeSelf).ToList(); - //float angleIncrement = 360f / platformsToSpawn; - //for (int i = 0; i < platformsToSpawn; i++) - //{ - // m_Platforms[i].transform.position = new Vector3( - // Mathf.Cos(i * angleIncrement * Mathf.Deg2Rad) * planeRadius, - // 0f, - // Mathf.Sin(i * angleIncrement * Mathf.Deg2Rad) * planeRadius - // ); - //} + m_Platforms = m_Platforms.Where(platform => platform.gameObject.activeSelf).ToList(); int[] platformIDs = m_Platforms.Select(p => p.PlatformID.Value).ToArray(); + + // Notify clients to enable corresponding platforms ClientEnablePlatformClientRpc(platformIDs); } + /// + /// ClientRpc to enable platforms on the client side. + /// [ClientRpc] private void ClientEnablePlatformClientRpc(int[] platformIDs) { - m_Platforms = GetComponentsInChildren(true).ToList(); // Ensure the platform list is refreshed - Debug.Log($"Client received platform IDs: {string.Join(",", platformIDs)}"); - Debug.Log($"Client platform list count: {m_Platforms.Count}"); + m_Platforms = GetComponentsInChildren(true).ToList(); + // Disable all platforms initially foreach (var platform in m_Platforms) { platform.gameObject.SetActive(false); - Debug.Log($"Disabled platform with ID: {platform.PlatformID.Value}"); } + // Enable specified platforms foreach (int id in platformIDs) { var platformToEnable = m_Platforms.FirstOrDefault(p => p.PlatformID.Value == id); if (platformToEnable != null) { platformToEnable.gameObject.SetActive(true); - Debug.Log($"Enabled platform with ID: {id}"); - } - else - { - Debug.LogError($"Platform with ID {id} not found on client."); } } - m_Platforms = m_Platforms.Where(platform => platform.gameObject.activeSelf).ToList(); + m_Platforms = m_Platforms.Where(platform => platform.gameObject.activeSelf).ToList(); } + + /// + /// Finds the nearest unoccupied platform to a given position. + /// Server-only method. + /// public Platform FindNearestUnoccupiedPlatform(Vector3 position) { if (!IsServer) @@ -136,49 +128,219 @@ namespace Unity.Multiplayer.Samples.BossRoom .FirstOrDefault(); } + /// + /// Checks if all platforms are occupied. + /// public bool AreAllPlatformsOccupied() { return m_Platforms.All(platform => platform.IsOccupied); } - /*public bool AssignPlayerToPlatform(ServerCharacter player) - { - if (!IsServer) - { - Debug.LogError("AssignPlayerToPlatform should only be called on the server."); - return false; - } - - var platform = m_Platforms.FirstOrDefault(p => !p.IsOccupied); - if (platform != null) - { - platform.Occupy(player); - return true; - } - - Debug.LogWarning($"No unoccupied platforms available for {player.name}."); - return false; - }*/ - + /// + /// Gets the platform occupied by a specific player. + /// public Platform GetPlatformOccupiedByPlayer(ServerCharacter player) { return m_Platforms.FirstOrDefault(p => p.IsOccupied && p.GetOccupierId() == player.OwnerClientId); } + /// + /// Checks if a platform is occupied. + /// public bool IsPlatformOccupied(Platform platform) { return platform.IsOccupied; } + /// + /// Gets the position of a platform by its ID. + /// public Vector3 GetPlatformPosition(int platformId) { var platform = m_Platforms.FirstOrDefault(p => p.PlatformID.Value == platformId); return platform ? platform.transform.position : Vector3.zero; } + /// + /// Gets a platform by its ID. + /// public Platform GetPlatformById(int platformId) { return m_Platforms.FirstOrDefault(p => p.PlatformID.Value == platformId); } } } + + +//using System.Collections; +//using System.Collections.Generic; +//using System.Linq; +//using Unity.BossRoom.Gameplay.GameplayObjects.Character; +//using Unity.Netcode; +//using UnityEngine; + +//namespace Unity.Multiplayer.Samples.BossRoom +//{ +// public class PlatformManager : NetworkBehaviour +// { +// public static PlatformManager Instance; +// public List m_Platforms; +// public int numberOfPlayers = 2; // Number of players (n) +// public float planeRadius = 4f; // Radius of the circular plane + +// private void Awake() +// { +// if (Instance != null && Instance != this) +// { +// Destroy(gameObject); +// } +// else +// { +// Instance = this; +// } +// } + +// private void Start() +// { +// if (IsServer) +// { +// m_Platforms = GetComponentsInChildren(true).ToList(); +// for (int i = 0; i < m_Platforms.Count; i++) +// { +// m_Platforms[i].AssignID(i + 1); // Initialize platforms with unique IDs +// } +// StartCoroutine(DelayedServerSetup()); +// } +// else +// { +// StartCoroutine(DelayedClientSetup()); // Delay to give time to load +// } +// } + +// /// +// /// Coroutine to delay server-side setup. +// /// +// private IEnumerator DelayedServerSetup() +// { +// yield return new WaitForSeconds(0.5f); // Delay for 0.5 seconds +// PlatformSelection(); // Call ServerRpc after delay +// } + +// /// +// /// Coroutine to delay client-side setup. +// /// +// private IEnumerator DelayedClientSetup() +// { +// yield return new WaitForSeconds(0.5f); +// m_Platforms = GetComponentsInChildren(true).ToList(); // Populate client platform list +// Debug.Log($"Client platform list initialized. Platform count: {m_Platforms.Count}"); +// } +// private void PlatformSelection() +// { +// int platformsToSpawn = PlayerPrefs.GetInt("NumberOfLobbyPlayers") - 1; + +// m_Platforms.ForEach(platform => platform.gameObject.SetActive(false)); +// Debug.Log("Disabled all platforms on the server."); + +// if (platformsToSpawn > 0) +// { +// for (int i = 0; i < platformsToSpawn; i++) +// { +// m_Platforms[i].gameObject.SetActive(true); +// Debug.Log($"Enabled platform with ID {m_Platforms[i].PlatformID.Value} on server."); +// } +// } +// m_Platforms = m_Platforms.Where(platform => platform.gameObject.activeSelf).ToList(); +// int[] platformIDs = m_Platforms.Select(p => p.PlatformID.Value).ToArray(); +// ClientEnablePlatformClientRpc(platformIDs); +// } + +// [ClientRpc] +// private void ClientEnablePlatformClientRpc(int[] platformIDs) +// { +// m_Platforms = GetComponentsInChildren(true).ToList(); // Ensure the platform list is refreshed +// Debug.Log($"Client received platform IDs: {string.Join(",", platformIDs)}"); +// Debug.Log($"Client platform list count: {m_Platforms.Count}"); + +// foreach (var platform in m_Platforms) +// { +// platform.gameObject.SetActive(false); +// Debug.Log($"Disabled platform with ID: {platform.PlatformID.Value}"); +// } + +// foreach (int id in platformIDs) +// { +// var platformToEnable = m_Platforms.FirstOrDefault(p => p.PlatformID.Value == id); +// if (platformToEnable != null) +// { +// platformToEnable.gameObject.SetActive(true); +// Debug.Log($"Enabled platform with ID: {id}"); +// } +// else +// { +// Debug.LogError($"Platform with ID {id} not found on client."); +// } +// } +// m_Platforms = m_Platforms.Where(platform => platform.gameObject.activeSelf).ToList(); + +// } +// public Platform FindNearestUnoccupiedPlatform(Vector3 position) +// { +// if (!IsServer) +// { +// Debug.LogError("FindNearestUnoccupiedPlatform should only be called on the server."); +// return null; +// } + +// return m_Platforms +// .Where(platform => !platform.IsOccupied) +// .OrderBy(platform => Vector3.Distance(position, platform.transform.position)) +// .FirstOrDefault(); +// } + +// public bool AreAllPlatformsOccupied() +// { +// return m_Platforms.All(platform => platform.IsOccupied); +// } + +// /*public bool AssignPlayerToPlatform(ServerCharacter player) +// { +// if (!IsServer) +// { +// Debug.LogError("AssignPlayerToPlatform should only be called on the server."); +// return false; +// } + +// var platform = m_Platforms.FirstOrDefault(p => !p.IsOccupied); +// if (platform != null) +// { +// platform.Occupy(player); +// return true; +// } + +// Debug.LogWarning($"No unoccupied platforms available for {player.name}."); +// return false; +// }*/ + +// public Platform GetPlatformOccupiedByPlayer(ServerCharacter player) +// { +// return m_Platforms.FirstOrDefault(p => p.IsOccupied && p.GetOccupierId() == player.OwnerClientId); +// } + +// public bool IsPlatformOccupied(Platform platform) +// { +// return platform.IsOccupied; +// } + +// public Vector3 GetPlatformPosition(int platformId) +// { +// var platform = m_Platforms.FirstOrDefault(p => p.PlatformID.Value == platformId); +// return platform ? platform.transform.position : Vector3.zero; +// } + +// public Platform GetPlatformById(int platformId) +// { +// return m_Platforms.FirstOrDefault(p => p.PlatformID.Value == platformId); +// } +// } +//} diff --git a/Assets/SynchronizedTimer.cs b/Assets/SynchronizedTimer.cs index 3ca72d1..0962164 100644 --- a/Assets/SynchronizedTimer.cs +++ b/Assets/SynchronizedTimer.cs @@ -5,56 +5,58 @@ using UnityEngine; public class SynchronizedTimer : NetworkBehaviour { - public event Action OnTimerEnd; // Ensure it's public + public event Action OnTimerEnd; - [SerializeField] private TextMeshProUGUI timerText; // Reference to the TextMeshProUGUI component + [SerializeField] private TextMeshProUGUI timerText; - private NetworkVariable timer = new NetworkVariable(0f, NetworkVariableReadPermission.Everyone, NetworkVariableWritePermission.Server); - private bool isTimerRunning = false; + private NetworkVariable timer = new NetworkVariable( + 0f, + NetworkVariableReadPermission.Everyone, + NetworkVariableWritePermission.Server + ); - void Update() + private bool isTimerRunning = false; + private void Start() + { + timerText.gameObject.SetActive( false ); + } + private void Update() { if (IsServer && isTimerRunning) { - // Decrease the timer only on the server timer.Value -= Time.deltaTime; - if (timer.Value <= 0) { timer.Value = 0; isTimerRunning = false; - OnTimerEnd?.Invoke(); // Trigger the event on the server + OnTimerEnd?.Invoke(); } + UpdateTimerUI(); } - // Update the UI on all clients - UpdateTimerUI(); } - /// - /// Starts the timer. - /// - /// The duration of the timer in seconds. - [ServerRpc(RequireOwnership = false)] - public void StartTimerServerRpc(float time) + public void StartTimerServer(float time) { - if (!isTimerRunning) + if (!isTimerRunning && time > 0) { timer.Value = time; isTimerRunning = true; + timerTextEnablerClientRpc(); } } + [ClientRpc] + void timerTextEnablerClientRpc() + { + timerText.gameObject.SetActive ( true ); + + } - /// - /// Gets the remaining time on the timer. - /// - /// The remaining time in seconds. public float GetRemainingTime() { return timer.Value; } - // This method ensures the timer stays synchronized for clients private void OnEnable() { timer.OnValueChanged += OnTimerValueChanged; @@ -67,22 +69,19 @@ public class SynchronizedTimer : NetworkBehaviour private void OnTimerValueChanged(float oldValue, float newValue) { - if (!IsServer && newValue <= 0 && oldValue > 0) + if (newValue <= 0 && oldValue > 0) { - OnTimerEnd?.Invoke(); // Trigger the event on clients when timer reaches zero + OnTimerEnd?.Invoke(); } + UpdateTimerUI(); } - /// - /// Updates the TextMeshProUGUI with the remaining time. - /// private void UpdateTimerUI() { if (timerText != null) { int minutes = Mathf.FloorToInt(timer.Value / 60); int seconds = Mathf.FloorToInt(timer.Value % 60); - timerText.text = $"{minutes:D2}:{seconds:D2}"; } } diff --git a/Assets/TimerScript.cs b/Assets/TimerScript.cs index 7e14333..e4ffb1f 100644 --- a/Assets/TimerScript.cs +++ b/Assets/TimerScript.cs @@ -2,40 +2,47 @@ using System.Collections; using Unity.Multiplayer.Samples.Utilities; using Unity.Netcode; using UnityEngine; -using static TMPro.SpriteAssetUtilities.TexturePacker_JsonArray; public class TimerScript : MonoBehaviour { [SerializeField] private SynchronizedTimer timer; public ServerAdditiveSceneLoader serverAdditiveSceneLoader; - public int timeInSeconds=180; + public int timeInSeconds = 180; + void Start() { if (timer != null) { - timer.OnTimerEnd += HandleTimerEnd; // Subscribe to the event + timeInSeconds = 1200; + timer.OnTimerEnd += HandleTimerEnd; + Debug.Log("Timer started call sent"); StartCoroutine(Starter()); } } + IEnumerator Starter() { yield return new WaitUntil(() => serverAdditiveSceneLoader.m_SceneState == ServerAdditiveSceneLoader.SceneState.Loaded); - if (Unity.Netcode.NetworkManager.Singleton.IsServer) + if (NetworkManager.Singleton.IsServer) { - timer.StartTimerServerRpc(timeInSeconds); // Start a 3-minute timer + yield return new WaitForSeconds(2.5f); + Debug.Log("Timer started call sent2"); + + timer.StartTimerServer(timeInSeconds); } } + private void HandleTimerEnd() { Debug.Log("Timer has ended!"); - // Add logic for what happens when the timer ends Scoreboard.instance.FinalLeaderBoard(); } + private void OnDestroy() { if (timer != null) { - timer.OnTimerEnd -= HandleTimerEnd; // Unsubscribe to avoid memory leaks + timer.OnTimerEnd -= HandleTimerEnd; } } }