Docs: reduce over-documentation across gameplay scripts

Trim restated narration, dead commented-out code, and oversized class
headers; keep all why-comments (authority, timing, edge cases), tooltips,
and serialization caveats.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
adminandClaude Fable 5 committed 2026-07-02 10:08:28 +02:00
1 parent 882d30797e
commit 066e308cde
21 files changed
+478 -902

No files matched your search

+24 -54
View File
@@ -30,9 +30,6 @@ public class GameModeManager : MonoBehaviour
[Tooltip("First-person camera. Empty = found automatically. Absent = First Person is left out of the cycle.")]
public FirstPersonController firstPerson;
//[Tooltip("Insect / surface-walk controller. Empty = found automatically.")]
//public InsectController insect;
[Header("Switching")]
[Tooltip("Key that cycles to the next mode.")]
#if ENABLE_INPUT_SYSTEM
@@ -49,7 +46,6 @@ public class GameModeManager : MonoBehaviour
public MeshPainter Painter => painter;
public FreeCamController FreeCam => freeCam;
public FirstPersonController FirstPerson => firstPerson;
//public InsectController Insect => insect;
/// <summary>Raised after a mode switch finishes (the new mode's Enter has already run).
/// Argument = the now-active mode. Used by UI (e.g. the paint HUD) to follow the mode.</summary>
@@ -81,7 +77,6 @@ public class GameModeManager : MonoBehaviour
// Include inactive so a freecam rig that starts disabled is still found and wired.
if (!freeCam) freeCam = FindFirstObjectByType<FreeCamController>(FindObjectsInactive.Include);
if (!firstPerson) firstPerson = FindFirstObjectByType<FirstPersonController>(FindObjectsInactive.Include);
//if (!insect) insect = FindFirstObjectByType<InsectController>();
BuildModes();
}
@@ -104,22 +99,19 @@ public class GameModeManager : MonoBehaviour
switch (role)
{
case PlayerRole.Hunter:
// Hunter: first person + paint. Index 0 (First Person, if its rig exists) is the start mode.
if (firstPerson) _modes.Add(new FirstPersonMode());
_modes.Add(new PaintMode());
break;
case PlayerRole.Hider:
// Hider: third person (player control) + paint + free cam. Index 0 (Player Control) is the start.
if (player) _modes.Add(new PlayerControlMode());
_modes.Add(new PaintMode());
if (freeCam) _modes.Add(new FreeCamMode());
break;
default:
// No role: legacy full set, gated on whichever rigs exist. Player Control only joins when a
// gravity player is present (player-less pre-spawn stays in Paint, not a dead frozen mode);
// Free Cam / First Person only when their rigs exist, so non-networked scenes are unchanged.
// No role: legacy full set, gated on whichever rigs exist (a player-less pre-spawn
// stays in Paint rather than a dead frozen Player Control).
if (player) _modes.Add(new PlayerControlMode());
_modes.Add(new PaintMode());
if (freeCam) _modes.Add(new FreeCamMode());
@@ -181,15 +173,12 @@ public class GameModeManager : MonoBehaviour
player = localPlayer;
// The painter lives on the player (per-avatar), so bind the local one - UNCONDITIONALLY. On a
// lobby->match respawn the previous avatar is despawned and the role variant spawned in the same
// server frame; the old painter is Destroy-pending (still non-null) when this runs, so a
// `if (!painter)` guard would keep the stale reference and the new avatar's painter would never be
// mode-toggled - it would paint in every mode. Always re-point to the fresh avatar.
// Re-point UNCONDITIONALLY: on a lobby->match respawn the old painter is Destroy-pending (still
// non-null), so a `if (!painter)` guard would keep the stale reference and the new avatar's
// painter would never be mode-toggled.
painter = localPlayer.GetComponentInChildren<MeshPainter>(true);
PainterChanged?.Invoke(painter);
// Point the cameras at the avatar's follow target.
Transform camTarget = localPlayer.transform.Find("CameraTarget");
if (cameraInput)
{
@@ -198,9 +187,8 @@ public class GameModeManager : MonoBehaviour
{
vcam.Follow = camTarget;
vcam.LookAt = camTarget;
// Follow is now the new avatar's target, so its lossyScale is live - start the camera at this
// avatar's scaled default zoom (Hider pulls in, Hunter pushes out) instead of inheriting the
// previous avatar's radius.
// Follow (and its lossyScale) is live now - start at this avatar's scaled default zoom
// instead of inheriting the previous avatar's radius.
cameraInput.ResetZoom();
}
}
@@ -212,17 +200,14 @@ public class GameModeManager : MonoBehaviour
ActiveMode?.Exit();
_activeIndex = -1;
// Lobby/neutral avatar (base Player prefab) -> full mode set; match avatar (Hunter/Hider variant)
// -> only its role's modes. Scope is baked per prefab variant, so it follows the spawned avatar
// with no replicated-phase timing race. (Mid-match spectators take a separate, empty prefab and
// bind via BindSpectator, not here.)
// Lobby avatar -> full set; match variant -> its role's modes. Scope is baked per prefab
// variant, so it follows the spawned avatar with no replicated-phase timing race.
if (setup && setup.ScopedModes)
BuildModes(setup.Role);
else
BuildModes(null);
// Role lists are ordered so index 0 is the start mode (Hunter -> First Person, Hider -> Player
// Control); the full lobby set starts at Player Control too.
// Index 0 is each set's intended start mode.
SwitchTo(0);
}
@@ -246,9 +231,8 @@ public class GameModeManager : MonoBehaviour
painter = null;
PainterChanged?.Invoke(null);
// No SwitchTo runs here (the cycle is now empty), so notify mode-following UI explicitly that
// there is no active mode - otherwise the paint HUD, which only hides via ModeChanged, would stay
// open back in Main after a shutdown that happened while PaintMode was active.
// The cycle is empty (no SwitchTo runs), so notify mode-following UI explicitly - otherwise the
// paint HUD (hides only via ModeChanged) would stay open after a shutdown during PaintMode.
ModeChanged?.Invoke(null);
if (cameraInput)
@@ -260,18 +244,11 @@ public class GameModeManager : MonoBehaviour
}
/// <summary>
/// Pauses or resumes local gameplay for a full-screen modal overlay (the online session panel, opened
/// with Esc in the lobby/map). Pausing frees the OS cursor and suppresses ALL local input - movement,
/// painting, camera look and the mode-switch key - WITHOUT tearing down the mode cycle, so resuming
/// re-enters the exact mode that was active and restores its camera/cursor state.
///
/// Crucially it does NOT Exit the active mode while pausing: the First-Person / Free-Cam rigs keep their
/// CinemachineCamera at its live priority, so the view stays frozen exactly where it is instead of
/// blending back to the orbit camera (the camera "jump" when the menu opened). Pausing therefore only
/// disables each rig's per-frame look input - dropping the controller's <c>enabled</c> freezes its look
/// without touching its priority - and parks the orbit rig in Disabled so it stops re-grabbing the cursor
/// every frame. Resuming re-runs the same mode's Enter(); because no priority was lowered, that mode's
/// snap-to-current-view is a no-op, so there is no jump on close either. No-op if unchanged.
/// Pauses/resumes local gameplay for a full-screen modal overlay (the Esc session panel). Suppresses
/// ALL local input and frees the cursor WITHOUT tearing down the mode cycle, so resuming re-enters
/// the exact mode that was active. Deliberately never Exits the active mode: the FP/free-cam vcam
/// keeps its priority, so the view stays frozen instead of blending back to the orbit camera (no
/// jump on open), and the resumed mode's snap-to-current-view is a no-op (no jump on close).
/// </summary>
public void SetPaused(bool paused)
{
@@ -283,12 +260,9 @@ public class GameModeManager : MonoBehaviour
_resumeIndex = _activeIndex;
_activeIndex = -1; // bookkeeping: no live mode while paused (Tick won't run)
// Freeze every input source but leave the active camera rig untouched (priority unchanged) so the
// view stays put. Painting/movement run off their own flags; the FP/freecam rigs drive their own
// CinemachineCamera each frame, so dropping their `enabled` freezes the look in place WITHOUT
// lowering priority; the orbit rig re-asserts the cursor each frame from its LookMode, so a
// Disabled look-mode keeps the cursor free every frame. At most one camera rig is ever enabled,
// so disabling both here is safe regardless of which mode was active.
// Freeze every input source without touching vcam priorities: dropping the FP/freecam
// `enabled` freezes their look in place; a Disabled orbit look-mode stops the per-frame
// cursor re-grab. At most one rig is ever enabled, so disabling both is safe.
if (player) player.ControlEnabled = false;
if (painter) painter.PaintingEnabled = false;
if (firstPerson) firstPerson.enabled = false;
@@ -309,9 +283,7 @@ public class GameModeManager : MonoBehaviour
_resumeIndex = -1;
if (resume >= 0 && resume < _modes.Count)
{
// Re-Enter the SAME mode (it was never Exited). The active rig still holds the current view,
// so Enter()'s sync-to-current-view is a no-op -> no jump. Enter restores control/painting/
// look + cursor and re-shows the HUD.
// Re-Enter the SAME mode (never Exited): its sync-to-current-view is a no-op -> no jump.
_activeIndex = resume;
ActiveMode.Enter();
ModeChanged?.Invoke(ActiveMode);
@@ -326,10 +298,8 @@ public class GameModeManager : MonoBehaviour
if (_paused) return;
if (_modes.Count == 0) return;
// Match resolution (the end-of-match reveal window) is watch-only: painting is off. Force out of Paint
// mode and keep the switch key from re-entering it. Local + owner by construction - this manager drives
// only the local avatar's cycle; remotes have no modes. No restore needed: the match ends by despawning
// and respawning the avatar, which rebuilds the cycle at index 0.
// Resolution (the reveal window) is watch-only: force out of Paint and keep the switch key from
// re-entering. No restore needed - the end-of-match respawn rebuilds the cycle at index 0.
bool suppressPaint = PaintSuppressed();
if (suppressPaint && ActiveMode is PaintMode)
{
@@ -388,7 +358,7 @@ public class GameModeManager : MonoBehaviour
private bool WasSwitchPressed()
{
if (TypingGuard.IsTyping) return false; // don't switch modes while typing in a text field
if (TypingGuard.IsTyping) return false;
#if ENABLE_INPUT_SYSTEM
return Keyboard.current != null && Keyboard.current[switchKey].wasPressedThisFrame;
#else