Block escape/tab menu while loading locally (join sync + Loading phase)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
adminandClaude Fable 5 committed 2026-07-12 15:30:31 +02:00
1 parent cab7590774
commit 782c3b4381
2 files changed
+31

No files matched your search

@@ -103,6 +103,10 @@ public class OverviewMenu : MonoBehaviour
matchResultScreen.Close();
else if (_open)
Close(resume: true);
// Loading (joining a session, or the pre-match Loading barrier): the scene/avatar is mid-setup,
// pausing or switching modes here corrupts the camera rigs - Esc/Tab do nothing.
else if (MatchManager.Instance && MatchManager.Instance.IsLoadingLocally)
{ }
// Paint mode: Esc exits back to the camera mode instead of opening the menu. Player Control
// first; the hunter's role-scoped set has none, so it falls through to First Person.
else if (gameMode && gameMode.EffectiveMode is PaintMode)
+27
View File
@@ -208,12 +208,22 @@ public class MatchManager : MonoBehaviour
private const string PreMatchTag = "PreMatch"; // scene props destroyed when seek starts
// Local loading trackers (see IsLoadingLocally). Two flags because a join sync fires per-scene
// LoadComplete events WHILE the synchronization is still running - one boolean would clear early.
private bool _syncingLocally; // NGO client synchronization (join) in flight
private bool _sceneOpLocally; // additive scene load/unload in flight on this machine
/// <summary>True while a match sub-phase (Hide/Seek/Resolution) is running on this machine.</summary>
public bool MatchActive => _subPhase != MatchSubPhase.None;
/// <summary>This machine's current sub-phase (mirror of the server's broadcast).</summary>
public MatchSubPhase LocalSubPhase => _subPhase;
/// <summary>The running match's mode (mirror of the server's choice). Drives per-client hider visibility.</summary>
public MatchMode LocalMatchMode => _localMode;
/// <summary>True while THIS machine is loading: joining a session (NGO client synchronization / an
/// additive scene load in flight) or held in the pre-match Loading barrier. The overview menu blocks
/// itself during this - pausing/switching modes mid-setup corrupts the camera rigs.</summary>
public bool IsLoadingLocally =>
_syncingLocally || _sceneOpLocally || _subPhase == MatchSubPhase.Loading;
/// <summary>Seconds left in the current sub-phase for the HUD (clamped to 0; cosmetic).</summary>
public float LocalPhaseRemaining => Mathf.Max(0f, _phaseEndTime - Time.time);
@@ -491,6 +501,8 @@ public class MatchManager : MonoBehaviour
_skipPhase = false;
_hooked = false;
_sceneReady = false;
_syncingLocally = false;
_sceneOpLocally = false;
_hasAuthorityClient = false;
_isLocalAuthority = false;
Phase = MatchPhase.Lobby;
@@ -523,6 +535,21 @@ public class MatchManager : MonoBehaviour
// instantiation context) - NGO additive loads don't promote the active scene on their own.
private void OnSceneEvent(SceneEvent e)
{
// Track this machine's own in-flight loads (drives IsLoadingLocally). Begin/complete events for
// OTHER clients also arrive on the server - filter to the local client id.
if (e.ClientId == _net.LocalClientId)
{
switch (e.SceneEventType)
{
case SceneEventType.Synchronize: _syncingLocally = true; break;
case SceneEventType.SynchronizeComplete: _syncingLocally = false; break;
case SceneEventType.Load:
case SceneEventType.Unload: _sceneOpLocally = true; break;
case SceneEventType.LoadComplete:
case SceneEventType.UnloadComplete: _sceneOpLocally = false; break;
}
}
if (e.SceneEventType != SceneEventType.LoadComplete) return;
if (e.SceneName != lobbySceneName && e.SceneName != matchSceneName) return;
if (e.Scene.IsValid() && e.Scene.isLoaded) SceneManager.SetActiveScene(e.Scene);