using UnityEngine; /// /// Placeholder on-screen match HUD: the current sub-phase + countdown (top centre) and a hunter crosshair /// during the seek phase. Drawn with IMGUI (OnGUI) on purpose - it needs no Canvas / font asset authoring, /// so the match-state logic can be exercised immediately; swap it for a proper uGUI canvas once the look is /// finalised. Added at runtime by (AddComponent), so it rides the persistent /// manager object and reads on every machine. /// [DisallowMultipleComponent] public class MatchHud : MonoBehaviour { private GUIStyle _phaseStyle; private GUIStyle _timeStyle; private int _lastSecond = -1; // countdown text cache: OnGUI runs 2+ times per frame, private string _timeText = ""; // so the string is only rebuilt when the displayed second changes private void OnGUI() { var match = MatchManager.Instance; if (!match || !match.MatchActive) return; EnsureStyles(); int s = Mathf.CeilToInt(Mathf.Max(0f, match.LocalPhaseRemaining)); if (s != _lastSecond) { _lastSecond = s; _timeText = $"{s / 60:0}:{s % 60:00}"; } const float w = 360f; var phaseRect = new Rect((Screen.width - w) * 0.5f, 12f, w, 30f); var timeRect = new Rect(phaseRect.x, phaseRect.y + 28f, w, 36f); DrawShadowed(phaseRect, PhaseLabel(match.LocalSubPhase), _phaseStyle); DrawShadowed(timeRect, _timeText, _timeStyle); if (match.LocalSubPhase == MatchManager.MatchSubPhase.Seek && NetworkPlayerSetup.LocalViewerIsHunter()) DrawCrosshair(); } private static string PhaseLabel(MatchManager.MatchSubPhase phase) { switch (phase) { case MatchManager.MatchSubPhase.Hide: return "Verstecken"; case MatchManager.MatchSubPhase.Seek: return "Suchen"; case MatchManager.MatchSubPhase.Resolution: return "Auflösung"; default: return ""; } } private static void DrawCrosshair() { float cx = Screen.width * 0.5f; float cy = Screen.height * 0.5f; const float r = 8f, t = 2f; Color prev = GUI.color; GUI.color = new Color(1f, 1f, 1f, 0.85f); GUI.DrawTexture(new Rect(cx - r, cy - t * 0.5f, r * 2f, t), Texture2D.whiteTexture); GUI.DrawTexture(new Rect(cx - t * 0.5f, cy - r, t, r * 2f), Texture2D.whiteTexture); GUI.color = prev; } // One label drawn twice (dark offset behind, then the real colour) so it stays readable on any backdrop. private static void DrawShadowed(Rect r, string text, GUIStyle style) { if (string.IsNullOrEmpty(text)) return; Color real = style.normal.textColor; style.normal.textColor = new Color(0f, 0f, 0f, 0.7f); GUI.Label(new Rect(r.x + 1f, r.y + 1f, r.width, r.height), text, style); style.normal.textColor = real; GUI.Label(r, text, style); } private void EnsureStyles() { if (_phaseStyle == null) _phaseStyle = MakeCenteredBoldLabel(22); if (_timeStyle == null) _timeStyle = MakeCenteredBoldLabel(28); } private static GUIStyle MakeCenteredBoldLabel(int fontSize) { var style = new GUIStyle(GUI.skin.label) { alignment = TextAnchor.MiddleCenter, fontSize = fontSize, fontStyle = FontStyle.Bold, }; style.normal.textColor = Color.white; return style; } }