Mouse Look Cursor Issue

Hi, I am having an issue with mouse input and cursor locking. I have made a custom first person controller with mouse look all included within a single class. The mouse look works fine – except for the very first frame when the CursorLockState is first set to Locked. As far as I can tell, the cursor seems to jump from wherever it is originally positioned to the centre of the screen, which is ‘technically’ what is supposed to happen, but as a result the camera suddenly rotates to the new location of the mouse, which can be mildly disorientating. After the first frame, mouse input works fine.


Here is a section of code for mouse look:

[SerializeField] private float _mouseSensitivity = 6f;
private Vector2 _look;

private void GetInput()
{
    _look += (new Vector2(Input.GetAxisRaw("Mouse Y"), Input.GetAxisRaw("Mouse X")) * (_mouseSensitivity * 50)) * Time.fixedDeltaTime;
    _look.x = Mathf.Clamp(_look.x, -90f, 90f); // Clamps the vertical look angle so that player cannot look underneath themself
}

private void Look()
{
    // Locking & hiding cursor

    Cursor.lockState = CursorLockMode.Locked;
    Cursor.visible = false;

    // Rotates self & head based on look vector

    transform.rotation = Quaternion.AngleAxis(_look.y, Vector3.up);
    _head.localRotation = Quaternion.AngleAxis(_look.x, Vector3.left);
}

Both of these methods are called on Update(). The ‘_head’ field refers to the Camera’s Transform component


It appears that the further the mouse is from the centre of the screen, the further the camera uncontrollably rotates. I have tried using a few different methods to fix this, such as:

  • using LateUpdate instead of Update
  • using the Awake method
  • using CursorLockState.Confined, which causes more problems
  • using CursorLockState.None, which fixes the issue but is not what I want
  • using an IEnumerator to wait a few frames before locking the cursor

None of these approaches have worked for me.


I have looked at dozens of pages on Unity Answers and StackOverflow and have not found anything that helps me, so if anyone has any solutions please can you let me know. Thank you.

1 Like

I know I shouldn’t reply to my own thread, but I think I have found a solution. By adding a boolean value which is set to true after the mouse is first moved, the camera’s orientation can be reset on the first frame that mouse input is received, to avoid the camera “jumping” to the mouse position.


In the unlikely event that anyone has the same problem as me, try something like this:

bool _hasCamMoved = false;

private void GetInput()
{
    if(_hasCamMoved)
    {
        _look += (new Vector2(Input.GetAxisRaw("Mouse Y"), Input.GetAxisRaw("Mouse X")) * (_mouseSensitivity * 50)) * Time.fixedDeltaTime;
        _look.x = Mathf.Clamp(_look.x, -90f, 90f); // Clamps the vertical look angle so that player cannot look underneath themself
    }
    else
    {
        if(Input.GetAxisRaw("Mouse X") != 0 || Input.GetAxisRaw("Mouse Y") != 0)
        {
            _hasCamMoved = true;
            ResetCameraRotation(); // this stops the camera from "jumping"
        }
    }
}

private void ResetCameraRotation(bool setToCurrentOrientation = false)
{
    if(setToCurrentOrientation) // this could be used on Awake(), although I haven't tested this yet
    {
        _look.y = transform.rotation.y;
        _look.x = _head.localRotation.x;
    }

    transform.rotation = Quaternion.AngleAxis(_look.y, Vector3.up);
    _head.localRotation = Quaternion.AngleAxis(_look.x, Vector3.left);
}