Freeze hiders (pose + transform) during the resolution phase

While a match is in the resolution sub-phase, hiders that have not
been found hold their current pose and position: the pose graph is
frozen (mixer speed 0, current frame re-asserted) and owner input is
disabled while gravity/grounding keep them planted.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
adminandClaude Opus 4.8 committed 2026-07-01 21:52:46 +02:00
1 parent 96528524a6
commit ff034870fc
2 files changed
+59

No files matched your search

+36
View File
@@ -115,6 +115,8 @@ public class NetworkPlayerSetup : NetworkBehaviour
private ConcealmentMeter _concealment; // owner-only embedded-percent source (disabled on remotes)
private bool _xrayApplied;
private bool _lastXRay;
private bool _frozenApplied;
private bool _lastFrozen;
public override void OnNetworkSpawn()
{
@@ -238,6 +240,40 @@ public class NetworkPlayerSetup : NetworkBehaviour
UpdateVisibility();
UpdateEmbeddedReveal();
UpdateXRayReveal();
UpdateResolutionFreeze();
}
// Per-client. During the resolution phase every still-in-play hider is frozen in place on every machine:
// its pose graph holds the current frame (PlayerPoseController.Frozen) and, on the owning client, its
// movement input is cut (ControlEnabled) so the owner-authoritative transform stops and replicates as
// frozen. Mirrors the resolution X-ray reveal predicate. The pose flag is change-guarded (toggled only on
// a transition); the owner's ControlEnabled is re-asserted every frozen frame so a stray mode toggle can't
// quietly re-enable movement during the reveal. Nothing is restored — EndMatch despawns this avatar.
private void UpdateResolutionFreeze()
{
bool freeze = ComputeResolutionFreeze();
if (freeze && IsOwner)
{
var controller = GetComponent<PlayerCharacterController>();
if (controller) controller.ControlEnabled = false;
}
if (_frozenApplied && freeze == _lastFrozen) return;
_lastFrozen = freeze;
_frozenApplied = true;
var pose = GetComponent<PlayerPoseController>();
if (pose) pose.Frozen = freeze;
}
// True while THIS avatar is a still-in-play hider during the local resolution phase (the reveal window).
private bool ComputeResolutionFreeze()
{
var match = MatchManager.Instance;
return match && match.MatchActive &&
match.LocalSubPhase == MatchManager.MatchSubPhase.Resolution &&
role == PlayerRole.Hider && !_isFound.Value;
}
// Per-client visibility: each machine decides whether to render THIS avatar's body from the LOCAL