Search Unity

  1. Unity 6 Preview is now available. To find out what's new, have a look at our Unity 6 Preview blog post.
    Dismiss Notice
  2. Unity is excited to announce that we will be collaborating with TheXPlace for a summer game jam from June 13 - June 19. Learn more.
    Dismiss Notice

Resolved Drag Mouse and Hide Cursor

Discussion in 'Input System' started by LuGus-Jan, Dec 29, 2023.

  1. LuGus-Jan

    LuGus-Jan

    Joined:
    Oct 3, 2016
    Posts:
    181
    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:

    Code (CSharp):
    1. private void Awake()
    2. {
    3.     inputSettings.FindActionMap("Gameplay").Enable();
    4.  
    5.     InputAction rotateCameraAction = inputSettings.FindAction("RotateCamera");
    6.     rotateCameraAction.started += OnRotateCameraStarted;
    7.     rotateCameraAction.performed += OnCameraRotatePerformed;
    8.     rotateCameraAction.canceled += OnRotateCameraCanceled;
    9. }
    10.  
    11. private void OnRotateCameraStarted(InputAction.CallbackContext context)
    12. {
    13.     Cursor.visible = false;
    14.     Cursor.lockState = CursorLockMode.Locked;
    15.     Log.Error($"Camera rotation started.");
    16. }
    17.  
    18. private void OnRotateCameraCanceled(InputAction.CallbackContext context)
    19. {
    20.     Cursor.visible = true;
    21.     Cursor.lockState = CursorLockMode.None;
    22.     Log.Error($"Camera rotation canceled.");
    23. }
    24.  
    25. private void OnCameraRotatePerformed(InputAction.CallbackContext context)
    26. {
    27.     Cursor.visible = true;
    28.     Cursor.lockState = CursorLockMode.None;
    29.     Log.Error($"Camera rotation performed.");
    30. }
    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!
     
  2. LuGus-Jan

    LuGus-Jan

    Joined:
    Oct 3, 2016
    Posts:
    181
    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:

    Code (CSharp):
    1. public float RotationDelta =>
    2.     inputSettings.FindAction("RotateCameraToggle").IsPressed() ?
    3.         inputSettings.FindAction("RotateCamera").ReadValue<Vector2>().x :
    4.         0f;
    5.  
    6. private void Awake()
    7. {
    8.     inputSettings.FindActionMap("Gameplay").Enable();
    9.  
    10.     InputAction rotateCameraAction = inputSettings.FindAction("RotateCameraToggle");
    11.     rotateCameraAction.performed += OnCameraRotatePerformed;
    12.     rotateCameraAction.canceled += OnRotateCameraCanceled;
    13. }
    14.  
    15. private void OnRotateCameraCanceled(InputAction.CallbackContext context)
    16. {
    17.     Cursor.visible = true;
    18.     Cursor.lockState = CursorLockMode.None;
    19. }
    20.  
    21. private void OnCameraRotatePerformed(InputAction.CallbackContext context)
    22. {
    23.     Cursor.visible = true;
    24.     Cursor.lockState = CursorLockMode.None;
    25. }
    Screenshot 2023-12-30 at 11.18.43.png