Quick answer: Cursor.lockState = Locked also hides the cursor, and setting lockState = None does not restore visibility automatically. Always set Cursor.visible explicitly alongside lockState, and handle both on OnApplicationFocus regain.
Here is how to fix Unity mouse cursor disappearing in a build. Your game works fine in the editor — the cursor is visible, menus are clickable. You build the standalone player, run it, and the cursor is gone. You can still click things (or sometimes not), but there is no visual cursor. Or the cursor appears briefly, then vanishes when a certain menu opens. Or it disappears after alt-tabbing back to the game. The editor hides this class of bug because the editor always draws its own cursor in play mode regardless of your Cursor.visible setting.
The Symptom
In the standalone build, the OS cursor is not visible over the game window. Clicks may still register at the invisible cursor location. The editor does not reproduce the issue because the editor’s own cursor is always visible during play mode — Cursor.visible has no effect on the editor cursor, only on the built player’s OS cursor.
Common variants: cursor missing from first frame of the build, cursor visible on the main menu but missing once a level loads, cursor gone after ESC-opening a pause menu, or cursor reappears but fixed at the window center after alt-tab.
What Causes This
LockState hides the cursor as a side effect. Setting Cursor.lockState = CursorLockMode.Locked implicitly hides the cursor. This is documented but easy to miss. When you later set lockState = None to release the lock (for a pause menu or UI screen), Unity does not automatically set visible = true. The cursor stays hidden until you explicitly restore it.
Scene-scoped Cursor.visible assignment. A scene-specific script hides the cursor on scene load but nothing restores it when the scene unloads. If you toggle Cursor.visible = false in Start() of a gameplay scene, every time that scene loads the cursor hides — which is fine during gameplay but breaks if any UI overlay appears or the user pauses.
Focus loss and regain. When the game window loses focus (alt-tab, clicking another window), Unity automatically releases CursorLockMode.Locked. When focus returns, OnApplicationFocus(true) fires. If you reapply the lock but forget to reapply visibility state, or if your logic gets confused about which state should apply (pause menu up vs. gameplay), the cursor can end up invisible.
Hardware cursor texture broken. If you use Cursor.SetCursor() with a custom texture, the texture must be set to Cursor type in its import settings. If the texture is too large, uses an unsupported format, or is lost during an asset bundle load, Unity may fall back to no cursor rather than the default. The cursor is technically “set” but invisible.
Multi-monitor setups. On some Windows configurations, the cursor can move onto a secondary monitor and Unity loses track of it. This is especially common with exclusive fullscreen mode, where the cursor can get stuck off-screen.
The Fix
Step 1: Always set both properties together. Create a helper that sets both lockState and visible atomically, and use it everywhere instead of touching the properties individually.
using UnityEngine;
public static class CursorHelper
{
public static void Show()
{
Cursor.lockState = CursorLockMode.None;
Cursor.visible = true;
}
public static void LockAndHide()
{
Cursor.lockState = CursorLockMode.Locked;
Cursor.visible = false;
}
public static void ConfineAndShow()
{
Cursor.lockState = CursorLockMode.Confined;
Cursor.visible = true;
}
}
Never call Cursor.lockState = ... or Cursor.visible = ... directly anywhere else in the codebase. Route everything through the helper. This eliminates the “I set one but forgot the other” class of bug.
Step 2: Handle focus changes. Add an OnApplicationFocus handler that restores the cursor state your game expects.
void OnApplicationFocus(bool hasFocus)
{
if (hasFocus)
{
if (gameState == GameState.Playing)
CursorHelper.LockAndHide();
else
CursorHelper.Show();
}
}
The point of this handler is to normalize state after Unity’s auto-release of the cursor lock on focus loss. Without it, the cursor state after alt-tab is whatever Unity’s internal state happens to be, which is not necessarily what your game wants.
Step 3: Set explicit state on scene load. In every scene’s entry point, explicitly set the cursor state. Do not rely on the state from the previous scene carrying over. A main menu scene should call CursorHelper.Show() in its first Start(); a gameplay scene should call CursorHelper.LockAndHide().
Step 4: Verify custom cursor textures. If you use Cursor.SetCursor(), check that the texture has “Cursor” set as its Texture Type in the Inspector, that it is 32x32 or smaller (larger cursors may not render), and that “Read/Write Enabled” is on. Test the build on a machine other than your development machine — cursor issues often appear only on different hardware.
Debugging Checklist
Add a debug key that logs the current cursor state on demand:
if (Input.GetKeyDown(KeyCode.F9))
{
Debug.Log($"Cursor: visible={Cursor.visible}, " +
$"lockState={Cursor.lockState}");
}
Run the build, reproduce the cursor disappearing, then press F9. The log reveals which property is wrong. You can ship this as a cheat code or remove before release.
WebGL Considerations
On WebGL, Cursor.lockState = Locked can only be set in response to a user gesture (click, key press). If you try to lock in Start(), browsers reject it and the cursor stays visible and free. This is a browser security feature, not a Unity bug. Move the lock call into a click handler on your game-start button.
“Cursor state is one property conceptually and two properties in practice. Wrap both in a helper and never touch them directly again.”
Related Issues
For cursor lock issues specifically in browser builds, see HTML5 Game Setup Guide. For UI-related input bugs, Unity New Input System UI Not Working covers related input bug patterns.
Always touch lockState and visible together. Never one without the other.