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.
220 lines
7.5 KiB
C#
220 lines
7.5 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 { get; private set; }
|
|
public List<Platform> m_Platforms;
|
|
public Transform centerPoint;
|
|
public float shapeRadius = 5f;
|
|
|
|
private void Awake()
|
|
{
|
|
if (Instance != null && Instance != this)
|
|
{
|
|
Destroy(gameObject);
|
|
}
|
|
else
|
|
{
|
|
Instance = this;
|
|
}
|
|
}
|
|
|
|
private void Start()
|
|
{
|
|
if (IsServer)
|
|
{
|
|
InitializePlatforms();
|
|
StartCoroutine(DelayedServerSetup());
|
|
}
|
|
}
|
|
|
|
private void InitializePlatforms()
|
|
{
|
|
m_Platforms = GetComponentsInChildren<Platform>(true).ToList();
|
|
for (int i = 0; i < m_Platforms.Count; i++)
|
|
{
|
|
m_Platforms[i].AssignID(i + 1);
|
|
}
|
|
}
|
|
|
|
private IEnumerator DelayedServerSetup()
|
|
{
|
|
yield return new WaitForSeconds(0.5f);
|
|
PlatformSelection();
|
|
}
|
|
|
|
private void PlatformSelection()
|
|
{
|
|
int platformsToSpawn = PlayerPrefs.GetInt("NumberOfLobbyPlayers", 1) - 1;
|
|
|
|
// Disable all platforms initially
|
|
foreach (var platform in m_Platforms)
|
|
{
|
|
platform.gameObject.SetActive(false);
|
|
}
|
|
|
|
// Enable required platforms
|
|
for (int i = 0; i < platformsToSpawn; i++)
|
|
{
|
|
m_Platforms[i].gameObject.SetActive(true);
|
|
}
|
|
|
|
// Filter only active platforms
|
|
m_Platforms = m_Platforms.Where(platform => platform.gameObject.activeSelf).ToList();
|
|
int[] platformIDs = m_Platforms.Select(p => p.PlatformID.Value).ToArray();
|
|
|
|
// Arrange the active platforms
|
|
List<Vector3> arrangedPositions = ArrangePlatforms(m_Platforms);
|
|
|
|
// Ensure positions are not empty before sending RPC
|
|
if (platformIDs.Length != arrangedPositions.Count || arrangedPositions.Count == 0)
|
|
{
|
|
Debug.LogError($"[PlatformSelection] ERROR: Mismatch! platformIDs: {platformIDs.Length}, positions: {arrangedPositions.Count}");
|
|
return; // Prevent sending incorrect RPC
|
|
}
|
|
|
|
for (int i = 0; i < m_Platforms.Count; i++)
|
|
{
|
|
m_Platforms[i].transform.position = arrangedPositions[i];
|
|
m_Platforms[i].RefreshCollider();
|
|
}
|
|
|
|
// Send the data to all clients
|
|
SyncPlatformsClientRpc(platformIDs, arrangedPositions.ToArray());
|
|
}
|
|
|
|
|
|
private List<Vector3> ArrangePlatforms(List<Platform> activePlatforms)
|
|
{
|
|
int platformCount = activePlatforms.Count;
|
|
|
|
if (platformCount == 0)
|
|
{
|
|
Debug.LogError($"[ArrangePlatforms] No active platforms found!");
|
|
return new List<Vector3>();
|
|
}
|
|
|
|
float startAngle = 90f; // Start from top
|
|
List<Vector3> arrangedPositions = new List<Vector3>();
|
|
|
|
// Special case: If 2 platforms, place them opposite to each other
|
|
if (platformCount == 2)
|
|
{
|
|
arrangedPositions.Add(centerPoint.position + new Vector3(shapeRadius, 0, 0)); // Right side
|
|
arrangedPositions.Add(centerPoint.position + new Vector3(-shapeRadius, 0, 0)); // Left side
|
|
}
|
|
else
|
|
{
|
|
float angleStep = 360f / platformCount;
|
|
|
|
for (int i = 0; i < platformCount; i++)
|
|
{
|
|
float angle = startAngle + (i * angleStep);
|
|
float radians = angle * Mathf.Deg2Rad;
|
|
|
|
Vector3 newPosition = new Vector3(
|
|
centerPoint.position.x + shapeRadius * Mathf.Cos(radians),
|
|
centerPoint.position.y,
|
|
centerPoint.position.z + shapeRadius * Mathf.Sin(radians)
|
|
);
|
|
|
|
arrangedPositions.Add(newPosition);
|
|
Debug.Log($"[ArrangePlatforms] Assigned position {i}: {newPosition} to Platform ID: {activePlatforms[i].PlatformID.Value}");
|
|
}
|
|
}
|
|
|
|
Debug.Log($"[ArrangePlatforms] Successfully arranged {arrangedPositions.Count} platforms.");
|
|
return arrangedPositions;
|
|
}
|
|
|
|
|
|
[ClientRpc]
|
|
private void SyncPlatformsClientRpc(int[] platformIDs, Vector3[] positions)
|
|
{
|
|
Debug.Log($"[SyncPlatformsClientRpc] Received {platformIDs.Length} platforms to activate.");
|
|
|
|
if (platformIDs.Length != positions.Length)
|
|
{
|
|
Debug.LogError($"[SyncPlatformsClientRpc] Data mismatch! Platform IDs: {platformIDs.Length}, Positions: {positions.Length}");
|
|
return;
|
|
}
|
|
|
|
m_Platforms = GetComponentsInChildren<Platform>(true).ToList();
|
|
|
|
foreach (var platform in m_Platforms)
|
|
{
|
|
platform.gameObject.SetActive(false);
|
|
}
|
|
|
|
List<Platform> activatedPlatforms = m_Platforms
|
|
.Where(p => platformIDs.Contains(p.PlatformID.Value))
|
|
.OrderBy(p => p.PlatformID.Value)
|
|
.ToList();
|
|
|
|
if (activatedPlatforms.Count != platformIDs.Length)
|
|
{
|
|
Debug.LogError($"[SyncPlatformsClientRpc] ERROR: Expected {platformIDs.Length} platforms but found {activatedPlatforms.Count} on the client.");
|
|
return;
|
|
}
|
|
|
|
for (int i = 0; i < activatedPlatforms.Count; i++)
|
|
{
|
|
activatedPlatforms[i].gameObject.SetActive(true);
|
|
activatedPlatforms[i].transform.position = positions[i];
|
|
|
|
// Force Collider Refresh
|
|
activatedPlatforms[i].RefreshCollider();
|
|
|
|
Debug.Log($"[SyncPlatformsClientRpc] Activated Platform ID: {activatedPlatforms[i].PlatformID.Value} at {positions[i]}");
|
|
}
|
|
|
|
Debug.Log($"[SyncPlatformsClientRpc] Successfully activated {activatedPlatforms.Count} platforms.");
|
|
}
|
|
|
|
|
|
|
|
public Platform FindNearestUnoccupiedPlatform(Vector3 position)
|
|
{
|
|
if (!IsServer) 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 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);
|
|
}
|
|
}
|
|
}
|