Files
chameleon/Assets/Scripts/MatchHud.cs
T
adminandClaude Opus 4.8 382bfb36df Refactor scripts: dedup remainder, remove dead code, perf hardening
Iteration 4 over Assets/Scripts (no component/file splits, no Unity assets touched):

Dedup:
- Route inline cursor-release, material guards, Ctrl-held and undo/redo
  input through existing InputUtil / SetMatFloat helpers
- Add ungated InputUtil.KeyPressedThisFrame; GameplayKeyPressed builds on it
- Unify FindDeep/FindDeepChild into GeometryUtil.FindDeep

Dead code / stale docs:
- Remove unused code-gen bake path (HsvColorPicker.Build, PaintHud factory)
- Drop unreferenced symbols (SubPhaseChanged event, LocalPhaseDuration,
  IsLocalSceneMain, MouseSensitivity.Changed, IsPaused, InSession,
  NetworkControlled, PreviousPose, JointCount, voxel-count accessors)
- Fix incorrect PlayerRole / PaintHud / Pick / PlayerPose docs

Perf / robustness (behaviour-neutral):
- ConcealmentMeter.Evaluate: reuse vertex/topology buffers, two-pointer
  crossing count
- BuildMeshCaches: alloc-free vertex copy, cached topology/UVs
- Guard all PlayerPaintSync LogSync sites behind logSync
- Cache LocalViewerIsHunter / controller / CanShoot / TypingGuard lookups;
  dedup LocalIsHunter with MatchHud
- Change-guard RefreshEmissionColor and HeroCutout.Disarm
- Cache scene/countdown string comparisons per frame
- Grow NonAlloc buffers and log-once on saturation

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-02 13:33:18 +02:00

94 lines
3.5 KiB
C#

using UnityEngine;
/// <summary>
/// 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 <see cref="MatchManager"/> (AddComponent), so it rides the persistent
/// manager object and reads <see cref="MatchManager.Instance"/> on every machine.
/// </summary>
[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;
}
}