Cursor Lock State Not Working Unity 2019.4

I have an empty project with the simple implementation of locking the cursor to the center of the screen. The function does not appear to be working as described by the documentation. Is there further setup that I am unaware of? I have replicated this on two machines and in the editor as well as the built version of the project. The script does run and the CursorLockMode is successfully set to locked however the cursor is able to leave the center of the screen and its position is never reset under any circumstances.

The following script is attached to the main camera:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class LockCursor : MonoBehaviour
{
    // Start is called before the first frame update
    void Start()
    {
        Cursor.lockState = CursorLockMode.Locked;
    }

    // Update is called once per frame
    void Update()
    {
        Cursor.lockState = CursorLockMode.Locked;
    }
}

I’m partially able to duplicate your problem in 2019.4.18f, Windows 10.

The cursor does not disappear if it is outside the Game window when the game starts. That is, if I click the Play button at the top of the editor and leave the cursor at some point not inside the Game window, the cursor jumps to the middle of the Game window and (while wiggling a bit) stays there. If I click the Play button and move the cursor inside the Game window, when the game starts, the cursor vanishes and I cannot make it reappear without stopping the game. If I click the Play button and then click somewhere outside the Game window, when the games starts, the cursor stays outside the Game window and I can move it wherever I want, until I click in the Game window, at which point it moves to the center of the Game window and stays there.

So, try this: Click Play and then immediately move your cursor into the Game window. Does it vanish then?

1 Like

I wish I could say why it wasn’t working or even why the behavior returned to normal. But I got nothing. After some brutal testing last night, I was resolved to the fact it must be related to the engine or the operating system (Win10) since the implementation was so simple. After waking up and seeing your post, I re-ran the test project without any changes, but it now works as expected. My computer has been on the whole time and I can verify that restarting the project was not the reason it started working again. A real mystery if you ask me. I’m glad it works now though. Stevens-R-Miller, thank you for spending the time to reply to me. I took a look at your Oscilloscope asset and some of the other things on your website. That’s some cool stuff!

To clarify some debugging notes I took when the problem existed in case anyone else wants to investigate:

I can verify that when the issue was happening, the cursor would not jump to the middle of the game view on start or once the window was selected. The Debug statement would display that the CursorLockMode was Locked. But if I moved my mouse it would never be repositioned. I was about to implement a work-around using:

Mouse.current.WarpCursorPosition(new Vector2(x, y));

https://docs.unity3d.com/Packages/com.unity.inputsystem@1.0/manual/Mouse.html

Be advised that this moves the system’s actual mouse cursor, not just Unity’s internally-stored mouse position. This means that the user sees the cursor jumping to a different position, which is generally considered to be bad UX practice. If you don’t program a way to stop the warping, once you hit play you will have to close the project to regain control of the mouse. (to my knowledge)

Gosh, I do hate bugs that come and go on their own initiative. Makes you wonder if it will ever return. Only guesses that leaves me are about global settings, either project settings or Windows settings, that maybe change when you hit some keyboard shortcut. More than once, seemingly impossible behavior turns out to be a result of my having unknowingly pressed Ctrl-Alt-FunctionKey, or some other such keyboard fingerknot.

Glad you liked my stuff. More coming!

Lockstate doesn’t work in Editor properly but will work in Standalone on Mac or PC builds just fine.

For the Editor, I came up with a very legit way to move the mouse cursor and another to force a mouse click event because Unity is so annoying in not letting you do this when using Cursor.lockState. Now you can set Cursor.lockState and/or Cursor.visibility in Start() and call either of the following below to force the mouse to behave. (Verified working in macOS Big Sur, Unity 2021.1.17)

Stupid easy way to force mouse cursor position to center of game window in editor only from code:

using UnityEngine.InputSystem;
using UnityEngine.InputSystem.LowLevel;

public static void ForceMousePositionToCenterOfGameWindow()
    {
#if UNITY_EDITOR
        // Force the mouse to be in the middle of the game screen
        var game = UnityEditor.EditorWindow.GetWindow(typeof(UnityEditor.EditorWindow).Assembly.GetType("UnityEditor.GameView"));
        Vector2 warpPosition = game.rootVisualElement.contentRect.center;  // never let it move
        Mouse.current.WarpCursorPosition(warpPosition);
        InputState.Change(Mouse.current.position, warpPosition);
#endif
    }

Stupid easy way to force click in game window in editor only from code:

using UnityEngine.InputSystem;
using UnityEngine.InputSystem.LowLevel;

public static void ForceClickMouseButtonInCenterOfGameWindow()
    {
#if UNITY_EDITOR
        var game = UnityEditor.EditorWindow.GetWindow(typeof(UnityEditor.EditorWindow).Assembly.GetType("UnityEditor.GameView"));
        Vector2 gameWindowCenter = game.rootVisualElement.contentRect.center;
        Event leftClickDown = new Event();
        leftClickDown.button = 0;
        leftClickDown.clickCount = 1;
        leftClickDown.type = EventType.MouseDown;
        leftClickDown.mousePosition = gameWindow;
        game.SendEvent(leftClickDown);
#endif
    }
1 Like