Drag Mouse and Hide Cursor

Hi all

I’m a little stuck in trying to achieve my goal. In an RTS game I’m working on, I want my camera to rotate, and while it is rotating, I want the mouse cursor to be hidden and locked to the center of the screen. This was ‘easy’ enough to do with Unity’s old Input system, but I’m looking into the new one and I run into one specific issue.

My camera is already rotating while holding down the right mouse button. So far so good. However, I’d like to hide the cursor now and locking into place, and I was looking on doing this based on the started, canceld and performed events, like so:

private void Awake()
{
    inputSettings.FindActionMap("Gameplay").Enable();

    InputAction rotateCameraAction = inputSettings.FindAction("RotateCamera");
    rotateCameraAction.started += OnRotateCameraStarted;
    rotateCameraAction.performed += OnCameraRotatePerformed;
    rotateCameraAction.canceled += OnRotateCameraCanceled;
}

private void OnRotateCameraStarted(InputAction.CallbackContext context)
{
    Cursor.visible = false;
    Cursor.lockState = CursorLockMode.Locked;
    Log.Error($"Camera rotation started.");
}

private void OnRotateCameraCanceled(InputAction.CallbackContext context)
{
    Cursor.visible = true;
    Cursor.lockState = CursorLockMode.None;
    Log.Error($"Camera rotation canceled.");
}

private void OnCameraRotatePerformed(InputAction.CallbackContext context)
{
    Cursor.visible = true;
    Cursor.lockState = CursorLockMode.None;
    Log.Error($"Camera rotation performed.");
}

9553672--1350253--Screenshot 2023-12-30 at 00.31.45.png

The problem I’m running into is that started and canceled are called every frame while holding the right mouse button, so my cursor isn’t hidden and when locking it to center, it jerks the camera around.

Is there any way so that the started, canceled and performed events are only called once as desired by the concept/idea of this functionality? Or is there perhaps another way to achieve this?

Thanks!

I found a solution: make a separate action for toggling the rotation. When this toggle is performed, I hide the cursor. And in my input manager class, I check whether the toggle is pressed before providing values:

public float RotationDelta =>
    inputSettings.FindAction("RotateCameraToggle").IsPressed() ?
        inputSettings.FindAction("RotateCamera").ReadValue<Vector2>().x :
        0f;

private void Awake()
{
    inputSettings.FindActionMap("Gameplay").Enable();

    InputAction rotateCameraAction = inputSettings.FindAction("RotateCameraToggle");
    rotateCameraAction.performed += OnCameraRotatePerformed;
    rotateCameraAction.canceled += OnRotateCameraCanceled;
}

private void OnRotateCameraCanceled(InputAction.CallbackContext context)
{
    Cursor.visible = true;
    Cursor.lockState = CursorLockMode.None;
}

private void OnCameraRotatePerformed(InputAction.CallbackContext context)
{
    Cursor.visible = true;
    Cursor.lockState = CursorLockMode.None;
}

9554023--1350340--Screenshot 2023-12-30 at 11.18.43.png