You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
HighGroundRoyaleNetcode/Assets/Scripts/Gameplay/PlatformManager.cs

497 lines
17 KiB
C#

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<Platform> 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<Platform> platforms; // Assign all platforms in the Inspector
private List<Platform> activePlatforms = new List<Platform>(); // Stores only active platforms
private Dictionary<string, float> platformDistances = new Dictionary<string, float>(); // Stores distances
private List<float> sortedUniqueDistances = new List<float>(); // Stores unique sorted distances
public List<Transform> 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<Transform> 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<Transform> 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<float> uniqueDistances = new HashSet<float>();
// 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
/// <summary>
/// Initializes platform list and assigns unique IDs.
/// </summary>
private void InitializePlatforms()
{
m_Platforms = GetComponentsInChildren<Platform>(true).ToList();
for (int i = 0; i < m_Platforms.Count; i++)
{
m_Platforms[i].AssignID(i + 1); // Assign unique IDs to platforms
}
}
/// <summary>
/// Delayed server setup to allow other components to initialize.
/// </summary>
private IEnumerator DelayedServerSetup()
{
yield return new WaitForSeconds(0.5f);
PlatformSelection();
}
/// <summary>
/// Server-side logic to select and enable platforms based on player count.
/// </summary>
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);
}
/// <summary>
/// ClientRpc to enable platforms on the client side.
/// </summary>
[ClientRpc]
private void ClientEnablePlatformClientRpc(int[] platformIDs)
{
m_Platforms = GetComponentsInChildren<Platform>(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();
}
/// <summary>
/// Finds the nearest unoccupied platform to a given position.
/// Server-only method.
/// </summary>
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();
}
/// <summary>
/// Checks if all platforms are occupied.
/// </summary>
public bool AreAllPlatformsOccupied()
{
return m_Platforms.All(platform => platform.IsOccupied);
}
/// <summary>
/// Gets the platform occupied by a specific player.
/// </summary>
public Platform GetPlatformOccupiedByPlayer(ServerCharacter player)
{
return m_Platforms.FirstOrDefault(p => p.IsOccupied && p.GetOccupierId() == player.OwnerClientId);
}
/// <summary>
/// Checks if a platform is occupied.
/// </summary>
public bool IsPlatformOccupied(Platform platform)
{
return platform.IsOccupied;
}
/// <summary>
/// Gets the position of a platform by its ID.
/// </summary>
public Vector3 GetPlatformPosition(int platformId)
{
var platform = m_Platforms.FirstOrDefault(p => p.PlatformID.Value == platformId);
return platform ? platform.transform.position : Vector3.zero;
}
/// <summary>
/// Gets a platform by its ID.
/// </summary>
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<Platform> 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<Platform>(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
// }
// }
// /// <summary>
// /// Coroutine to delay server-side setup.
// /// </summary>
// private IEnumerator DelayedServerSetup()
// {
// yield return new WaitForSeconds(0.5f); // Delay for 0.5 seconds
// PlatformSelection(); // Call ServerRpc after delay
// }
// /// <summary>
// /// Coroutine to delay client-side setup.
// /// </summary>
// private IEnumerator DelayedClientSetup()
// {
// yield return new WaitForSeconds(0.5f);
// m_Platforms = GetComponentsInChildren<Platform>(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<Platform>(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);
// }
// }
//}