Files
2026-08-06 18:56:32 +03:00

116 lines
3.0 KiB
C#

using System;
using Unity.Netcode;
using UnityEngine;
public enum RoundPhase : byte
{
WaitingForPlayers,
WaitingForPlayersToLeave,
WorkInProgress
}
[RequireComponent(typeof(NetworkObject))]
public sealed class RoundGameLoopController : NetworkBehaviour
{
private readonly NetworkVariable<RoundPhase> phase = new(
RoundPhase.WaitingForPlayers,
NetworkVariableReadPermission.Everyone,
NetworkVariableWritePermission.Server);
private StartRoomZone startRoom;
public RoundPhase Phase => phase.Value;
public event Action<RoundPhase> PhaseChanged;
public override void OnNetworkSpawn()
{
phase.OnValueChanged += HandlePhaseChanged;
startRoom = FindFirstObjectByType<StartRoomZone>();
if (IsServer)
phase.Value = RoundPhase.WaitingForPlayers;
}
public override void OnNetworkDespawn()
{
phase.OnValueChanged -= HandlePhaseChanged;
}
private void Update()
{
if (!IsServer)
return;
if (startRoom == null)
startRoom = FindFirstObjectByType<StartRoomZone>();
if (startRoom == null)
return;
switch (phase.Value)
{
case RoundPhase.WaitingForPlayers:
if (AreAllPlayersInStartRoom())
phase.Value = RoundPhase.WaitingForPlayersToLeave;
break;
case RoundPhase.WaitingForPlayersToLeave:
if (AreAllPlayersOutsideStartRoom())
phase.Value = RoundPhase.WorkInProgress;
break;
}
}
private bool AreAllPlayersInStartRoom()
{
if (!TryGetConnectedPlayers(out int playerCount))
return false;
int playersInside = 0;
foreach (NetworkClient client in NetworkManager.ConnectedClients.Values)
{
if (client.PlayerObject != null && startRoom.Contains(client.PlayerObject.transform.position))
playersInside++;
}
return playersInside == playerCount;
}
private bool AreAllPlayersOutsideStartRoom()
{
if (!TryGetConnectedPlayers(out int playerCount))
return false;
int playersOutside = 0;
foreach (NetworkClient client in NetworkManager.ConnectedClients.Values)
{
if (client.PlayerObject != null && !startRoom.Contains(client.PlayerObject.transform.position))
playersOutside++;
}
return playersOutside == playerCount;
}
private bool TryGetConnectedPlayers(out int playerCount)
{
playerCount = 0;
if (NetworkManager == null || NetworkManager.ConnectedClients.Count == 0)
return false;
foreach (NetworkClient client in NetworkManager.ConnectedClients.Values)
{
if (client.PlayerObject == null)
return false;
playerCount++;
}
return playerCount > 0;
}
private void HandlePhaseChanged(RoundPhase _, RoundPhase current) =>
PhaseChanged?.Invoke(current);
}