Show live hunter/hider counts in match HUD
Count spawned role variants from a client-side avatar registry in NetworkPlayerSetup (network objects exist on every machine), so the counts work without server-only match state. MatchHud binds the two count texts and rewrites them only on change. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
1 parent
67f97df9f0
commit
6434e1c4fc
2 files changed
+38
-2
No files matched your search
@@ -1,3 +1,4 @@
|
||||
using System.Collections.Generic;
|
||||
using Unity.Netcode;
|
||||
using UnityEngine;
|
||||
|
||||
@@ -116,6 +117,7 @@ public class NetworkPlayerSetup : NetworkBehaviour
|
||||
|
||||
public override void OnNetworkSpawn()
|
||||
{
|
||||
_active.Add(this); // scoreboard registry (paired with OnNetworkDespawn)
|
||||
_bodyRenderers = GetComponentsInChildren<SkinnedMeshRenderer>(true);
|
||||
_painter = GetComponentInChildren<MeshPainter>(true);
|
||||
_concealment = GetComponentInChildren<ConcealmentMeter>(true);
|
||||
@@ -177,6 +179,7 @@ public class NetworkPlayerSetup : NetworkBehaviour
|
||||
|
||||
public override void OnNetworkDespawn()
|
||||
{
|
||||
_active.Remove(this);
|
||||
_isFound.OnValueChanged -= OnFoundChanged;
|
||||
}
|
||||
|
||||
@@ -377,6 +380,25 @@ public class NetworkPlayerSetup : NetworkBehaviour
|
||||
return _localViewerIsHunter;
|
||||
}
|
||||
|
||||
// Live scoreboard source. Every match avatar is a network object present on ALL machines, so counting the
|
||||
// spawned role variants is client-safe - no server-only match state (e.g. _pendingHiders) is needed.
|
||||
// Hunters = hunter variants; hiders = un-found hider variants (a Classic-found hider leaves the count, a
|
||||
// Conversion hit despawns the hider object and spawns a hunter one, so both sides update from the registry).
|
||||
private static readonly List<NetworkPlayerSetup> _active = new List<NetworkPlayerSetup>();
|
||||
|
||||
internal static void CountRoles(out int hunters, out int hiders)
|
||||
{
|
||||
hunters = 0;
|
||||
hiders = 0;
|
||||
for (int i = 0; i < _active.Count; i++)
|
||||
{
|
||||
var p = _active[i];
|
||||
if (!p || !p.scopedModes) continue; // ignore the neutral lobby avatar
|
||||
if (p.role == PlayerRole.Hunter) hunters++;
|
||||
else if (!p._isFound.Value) hiders++;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Places the freshly-spawned owner: role-specific spawn area first, then the shared area (a random
|
||||
/// point inside the collider), falling back to the deterministic client-id ring. Owner-authoritative -
|
||||
|
||||
@@ -31,14 +31,16 @@ public class MatchHud : MonoBehaviour
|
||||
[SerializeField] private GameObject _crosshair;
|
||||
|
||||
private int _lastSecond = -1;
|
||||
private int _lastHunters = -1;
|
||||
private int _lastHiders = -1;
|
||||
private MatchManager.MatchSubPhase _lastPhase = (MatchManager.MatchSubPhase)(-1);
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
if (!_canvas) _canvas = GetComponent<Canvas>();
|
||||
if (!_canvas || !_phaseText || !_timeText || !_crosshair)
|
||||
if (!_canvas || !_phaseText || !_timeText || !_crosshair || !_hunterCount || !_hiderCount)
|
||||
{
|
||||
Debug.LogError("[MatchHud] Unwired reference(s) - assign Canvas/Phase/Time/Crosshair in the Inspector.", this);
|
||||
Debug.LogError("[MatchHud] Unwired reference(s) - assign Canvas/Phase/Time/Crosshair/HunterCount/HiderCount in the Inspector.", this);
|
||||
enabled = false;
|
||||
return;
|
||||
}
|
||||
@@ -68,6 +70,18 @@ public class MatchHud : MonoBehaviour
|
||||
_timeText.text = $"{s / 60:0}:{s % 60:00}";
|
||||
}
|
||||
|
||||
NetworkPlayerSetup.CountRoles(out int hunters, out int hiders);
|
||||
if (hunters != _lastHunters)
|
||||
{
|
||||
_lastHunters = hunters;
|
||||
_hunterCount.text = hunters.ToString();
|
||||
}
|
||||
if (hiders != _lastHiders)
|
||||
{
|
||||
_lastHiders = hiders;
|
||||
_hiderCount.text = hiders.ToString();
|
||||
}
|
||||
|
||||
bool showCross = phase == MatchManager.MatchSubPhase.Seek && NetworkPlayerSetup.LocalViewerIsHunter();
|
||||
if (_crosshair.activeSelf != showCross) _crosshair.SetActive(showCross);
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user