using UnityEngine;
///
/// Teams mode: a central capture zone. The local player sends "inZone" messages
/// to the server while inside the zone. The server tallies scores.
/// Visualizes zone control by tinting the zone's renderer.
///
/// Setup: Create a flat Box/Plane in the center of the arena.
/// Add a BoxCollider set to "Is Trigger". Attach this script.
///
public class ZoneCapture : MonoBehaviour
{
public static ZoneCapture Instance { get; private set; }
[Header("Visual")]
[Tooltip("Neutral zone color")]
public Color neutralColor = new Color(0.5f, 0.5f, 0.6f, 0.5f);
[Tooltip("Red team controls color")]
public Color redColor = new Color(1f, 0.2f, 0.2f, 0.6f);
[Tooltip("Blue team controls color")]
public Color blueColor = new Color(0.2f, 0.5f, 1f, 0.6f);
[Header("Score Reporting")]
[Tooltip("How often (seconds) to send inZone=true to server while inside")]
public float reportInterval = 0.5f;
private bool _isLocalPlayerInZone = false;
private float _reportTimer = 0f;
private Renderer _renderer;
// Zone occupant counts (received via server state — approximated by remote player positions)
private int _redInZone = 0;
private int _blueInZone = 0;
void Awake()
{
Instance = this;
_renderer = GetComponent();
SetZoneColor(neutralColor);
}
void Start()
{
if (NetworkManager.Instance != null)
{
NetworkManager.Instance.OnPhaseChanged += OnPhaseChanged;
}
}
void OnDestroy()
{
if (NetworkManager.Instance != null)
NetworkManager.Instance.OnPhaseChanged -= OnPhaseChanged;
}
void OnPhaseChanged(string phase)
{
if (phase == "lobby" || phase == "roundEnd")
{
_isLocalPlayerInZone = false;
_redInZone = 0;
_blueInZone = 0;
SetZoneColor(neutralColor);
}
}
void Update()
{
if (!_isLocalPlayerInZone) return;
_reportTimer += Time.deltaTime;
if (_reportTimer >= reportInterval)
{
_reportTimer = 0f;
NetworkManager.Instance?.SendInZone(true);
}
// Update zone tint based on dominance
UpdateZoneColor();
}
void OnTriggerEnter(Collider other)
{
if (other.GetComponent() != null)
{
_isLocalPlayerInZone = true;
_reportTimer = 0f;
NetworkManager.Instance?.SendInZone(true);
}
// Count remote players in zone
var remote = other.GetComponent();
if (remote != null)
{
// team info would need to be tracked — skip for now, server handles scoring
}
}
void OnTriggerExit(Collider other)
{
if (other.GetComponent() != null)
{
_isLocalPlayerInZone = false;
NetworkManager.Instance?.SendInZone(false);
}
}
private void UpdateZoneColor()
{
// Read team scores from NetworkManager state for visual feedback
// For now use a pulsing neutral tint when local player is inside
float pulse = 0.7f + 0.3f * Mathf.Sin(Time.time * 3f);
Color c = neutralColor;
c.a = pulse * 0.6f;
SetZoneColor(c);
}
public void SetZoneColor(Color c)
{
if (_renderer == null) return;
var mat = _renderer.material;
if (mat.HasProperty("_BaseColor")) mat.SetColor("_BaseColor", c);
else mat.color = c;
}
}