MenuInput.cs
using Sandbox;
using SWB.Player;
// Frees the mouse cursor for menu UI.
//
// Mouse.Visible can't be set directly - the engine derives it each frame
// from whether the active input context is in UI mouse state:
//
// MouseCursorVisible = !mouseCaptureMode &&
// (activeMouse is not null && activeMouse.MouseState == InputState.UI);
//
// What actually holds it in gameplay mode is CameraMovement.FirstPerson()
// consuming Input.AnalogLook every frame for mouse-look. Switching that
// component off while a menu is open releases the pointer; switching it
// back on returns control to the player.
//
// Shared by the vendor and job board so they can't drift apart and leave
// the cursor stuck in whichever state the last one set.
public static class MenuInput
{
public static void SetMenuOpen( bool open )
{
var player = PlayerBase.Local;
if ( player is null )
return;
// PlayerBase caches this in OnAwake, which matters: component
// lookups skip DISABLED components by default, so searching for it
// here would find nothing once a menu had switched it off - and it
// would never get switched back on. Using the cached reference
// sidesteps that entirely.
if ( player.CameraMovement is not Component look )
return;
// MissionPlayerState turns mouse-look off to hand the camera over
// for spectating. Re-enabling it here would yank the view back off
// whoever they're watching, so leave it alone once they're out.
var outOfPlay = player.Components.Get<MissionPlayerState>()?.IsOut ?? false;
if ( outOfPlay )
return;
look.Enabled = !open;
}
}