Search Unity

Input System Raw Input from Mouse

Discussion in 'Input System' started by wedrk, Aug 11, 2020.

  1. wedrk

    wedrk

    Joined:
    Jul 15, 2018
    Posts:
    9
    I'm trying to make a FPS controller with the new Input System, but the camera movement is really jittery because the input system doesn't send input events until the mouse as moved an entire pixel. Is there anyway that I can get mouse input events in between pixels or just get the raw mouse input?
     
  2. Rene-Damm

    Rene-Damm

    Joined:
    Sep 15, 2012
    Posts:
    1,779
    Which platform? On Windows, mouse input is tapped through Raw Input and an update sent every time we get a WM_INPUT message for the mouse. Delta position updates correspond to lLastX and lLastY which *should* be what we get from the mouse in terms of mouse motion and not respect pixel boundaries.
     
  3. ahaynes100105

    ahaynes100105

    Joined:
    Jun 19, 2019
    Posts:
    1
    I'm getting the same problem on my windows PC and can't find a single resource online that can help me. Maybe there's a bug in the New Input System?
     
  4. NotElayn

    NotElayn

    Joined:
    Jun 12, 2019
    Posts:
    1
    Hello there,
    I can't be of much help to you as I'm a fairly inexperienced developer but I also was experiencing the same problems and got everything fixed. So I'll just tell you all the things I did.
    First, this is my InputAction Map:

    I then created two scripts, one named "InputManager", and the other named "PlayerController". By the way, the name of my action map c# script was PlayerControl.
    This is my InputManager.cs:
    Code (CSharp):
    1. using System;
    2. using UnityEngine;
    3. using UnityEngine.Events;
    4. using UnityEngine.InputSystem;
    5.  
    6. [Serializable]
    7. public class MouseMoveInputEvent : UnityEvent<Vector2> { }
    8.  
    9.  
    10. public class InputManager : MonoBehaviour
    11. {
    12.     PlayerControl playerControl;
    13.  
    14.     public MouseMoveInputEvent mouseMoveInputEvent;
    15.  
    16.     void Awake()
    17.     {
    18.         playerControl = new PlayerControl();
    19.     }
    20.  
    21.     void OnEnable()
    22.     {
    23.         playerControl.PlayerControls.Enable();
    24.        playerControl.PlayerControls.Look.performed += OnMouseMovePerformed;
    25.     }
    26.  
    27.     void OnDisable()
    28.     {
    29.         playerControl.PlayerControls.Disable();
    30.     }
    31.  
    32.     void OnMouseMovePerformed(InputAction.CallbackContext context)
    33.     {
    34.         Vector2 mouseInput = context.ReadValue<Vector2>();
    35.         // Account for scaling applied directly in Windows code by old input system.
    36.         mouseInput *= 0.5f;
    37.         // Account for sensitivity setting on old Mouse X and Y axes.
    38.         mouseInput *= 0.1f;
    39.  
    40.         mouseMoveInputEvent.Invoke(mouseInput);
    41.     }
    42.  
    43. }
    I then created a Player with the following structure:

    I placed the InputManager script on GameManager object like so:

    And then in the PlayerController.cs:
    Code (CSharp):
    1. [SerializeField] Transform playerCam;
    2.     [SerializeField] Vector2 mouseSensitivity;
    3.     [SerializeField] bool isInvert = false;
    4.     [SerializeField] bool isLock;
    5.  
    6.     float cameraPitch = 0.0f;
    7.  
    8.     InputManager inputManager;
    9.     Vector2 mouseInput;
    10.  
    11.     void Start()
    12.     {
    13.         SetCursorLocked(isLock);
    14.     }
    15.    
    16.     void Update()
    17.     {
    18.         UpdateMouseLook();
    19.     }
    20.  
    21.     void UpdateMouseLook()
    22.     {
    23.         Vector2 mouseDelta = new Vector2(mouseInput.x, mouseInput.y);
    24.        
    25.         if(isInvert)
    26.             cameraPitch += mouseDelta.y * mouseSensitivity.y;
    27.         else
    28.             cameraPitch -= mouseDelta.y * mouseSensitivity.y;
    29.  
    30.         cameraPitch = Mathf.Clamp(cameraPitch, -90.0f, 90.0f);
    31.  
    32.         playerCam.localEulerAngles = Vector3.right * cameraPitch;
    33.  
    34.         transform.Rotate(Vector3.up * mouseDelta.x * mouseSensitivity.x);
    35.     }
    36.    
    37.     public void OnMouseInput(Vector2 mouseInput)
    38.     {
    39.         this.mouseInput = mouseInput;
    40.     }
    41.  
    42.     void SetCursorLocked(bool isLocked)
    43.     {
    44.         Cursor.lockState = isLocked ? CursorLockMode.Locked : CursorLockMode.None;
    45.         Cursor.visible = isLocked ? false : true;
    46.     }
    47. }
    This was the gist of it. Make sure to make the "Look" Action Pass through and Vector2, and also multiply the inputs with those "magic numbers" in the InputManager.cs. That eliminated the "jittery" movement for me. Sorry if there is any mistake in my language or code as English is not my first language and I'm not a developer with much experience, just a teenager having fun ;)