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) private void Awake() { if (Instance != null && Instance != this) { Destroy(gameObject); } else { Instance = this; } } private void Start() { if (IsServer) { InitializePlatforms(); StartCoroutine(DelayedServerSetup()); } } #region DistancePlatform public List platforms; // Assign all platforms in the Inspector private List activePlatforms = new List(); // Stores only active platforms private Dictionary platformDistances = new Dictionary(); // Stores distances private List sortedUniqueDistances = new List(); // Stores unique sorted distances public List platformTransforms; // Assign platform GameObjects here public Transform centerPoint; // Center position where the shape will form public float shapeRadius = 5f; void Starter() { UpdateActivePlatforms(); PrecomputeDistances(); } public void ArrangePlatforms() { // Get only active platforms List activePlatforms = platformTransforms.Where(p => p.gameObject.activeSelf).ToList(); int count = activePlatforms.Count; if (count < 3) { Debug.LogWarning("Not enough platforms to form a shape!"); return; } // Arrange them in a regular polygon shape PlacePlatformsInShape(activePlatforms, count); } private void PlacePlatformsInShape(List platforms, int count) { float angleStep = 360f / count; // Equal angles for each platform float startAngle = 90f; // Start from the top (adjust if needed) for (int i = 0; i < count; i++) { float angle = startAngle + (i * angleStep); float radians = angle * Mathf.Deg2Rad; // Calculate new position using circle formula Vector3 newPosition = new Vector3( centerPoint.position.x + shapeRadius * Mathf.Cos(radians), centerPoint.position.y, centerPoint.position.z + shapeRadius * Mathf.Sin(radians) ); // Move platform to its new position platforms[i].position = newPosition; } } public void UpdateActivePlatforms() { // Refresh the active platforms list activePlatforms = platforms.Where(p => p.gameObject.activeSelf).ToList(); } private void PrecomputeDistances() { platformDistances.Clear(); sortedUniqueDistances.Clear(); if (activePlatforms.Count < 2) { Debug.LogWarning("Not enough active platforms to calculate distances."); return; } HashSet uniqueDistances = new HashSet(); // Compute and store distances between all active platform pairs for (int i = 0; i < activePlatforms.Count; i++) { for (int j = i + 1; j < activePlatforms.Count; j++) { Platform platformA = activePlatforms[i]; Platform platformB = activePlatforms[j]; float rawDistance = Vector3.Distance(platformA.transform.position, platformB.transform.position); float roundedDistance = Mathf.Round(rawDistance * 100f) / 100f; // Rounds to 2 decimal places uniqueDistances.Add(roundedDistance); string key = GetPlatformKey(platformA, platformB); platformDistances[key] = roundedDistance; } } // Convert unique distances into a sorted list sortedUniqueDistances = uniqueDistances.OrderBy(d => d).ToList(); Debug.Log("Sorted unique distances: " + string.Join(", ", sortedUniqueDistances)); } public float CalculateScore(Platform platformA, Platform platformB) { if(platformA== null) { Debug.Log("platformA is null"); } if(platformB == null) { Debug.Log("platformB is null"); } if (!platformA.gameObject.activeSelf || !platformB.gameObject.activeSelf) { Debug.Log("One or both selected platforms are not active."); return -1; } Debug.Log("PlatformKey getter"); string key = GetPlatformKey(platformA, platformB); Debug.Log("PlatformKey getter2"); if (!platformDistances.ContainsKey(key)) { Debug.LogError("Distance for selected platforms not found!"); return -1; } float distance = platformDistances[key]; float scoreMultiplier = GetMultiplier(distance); Debug.Log($"Platforms {platformA.name} & {platformB.name} selected. Distance: {distance:F2}, Score Multiplier: {scoreMultiplier}"); return scoreMultiplier; } private float GetMultiplier(float distance) { if (sortedUniqueDistances.Count == 0) { return 1.0f; // Default if no distances are calculated } // Find the index of the selected distance in the sorted list int index = sortedUniqueDistances.IndexOf(distance); // Multiplier starts from 1.0 and increases by 0.1 per step return 1.0f + (index * 0.1f); } private string GetPlatformKey(Platform platformA, Platform platformB) { return platformA.name + "_" + platformB.name; } #endregion /// /// Initializes platform list and assigns unique IDs. /// private void InitializePlatforms() { 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 } } /// /// Delayed server setup to allow other components to initialize. /// private IEnumerator DelayedServerSetup() { yield return new WaitForSeconds(0.5f); PlatformSelection(); } /// /// Server-side logic to select and enable platforms based on player count. /// private void PlatformSelection() { int platformsToSpawn = PlayerPrefs.GetInt("NumberOfLobbyPlayers",1) - 1; //int platformsToSpawn = 2; // Disable all platforms initially foreach (var platform in m_Platforms) { 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(); 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(); // Disable all platforms initially foreach (var platform in m_Platforms) { platform.gameObject.SetActive(false); } // 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); } } m_Platforms = m_Platforms.Where(platform => platform.gameObject.activeSelf).ToList(); Starter(); } /// /// Finds the nearest unoccupied platform to a given position. /// Server-only method. /// 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(); } /// /// Checks if all platforms are occupied. /// public bool AreAllPlatformsOccupied() { return m_Platforms.All(platform => platform.IsOccupied); } /// /// 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); // } // } //}