Search Unity

  1. Are you interested in providing feedback directly to Unity teams? Sign up to become a member of Unity Pulse, our new product feedback and research community.
    Dismiss Notice

Mouse Delta Input

Discussion in 'Input System' started by caseyc, Mar 18, 2019.

  1. FernandoDarci

    FernandoDarci

    Joined:
    Jan 25, 2018
    Posts:
    13
    I don´t read all the posts, but I have a simplier solution:


    1. private void OnEnable()
    2. {
    3. {
    4. _inputActionReferenceAiming.action.performed += ctx => look = ctx.ReadValue<Vector2>();
    5. _inputActionReferenceAiming.action.canceled += ctx => look = new Vector2();

    6. _inputActionReferenceAiming.action.Enable();
    7. }

    8. }
     
  2. Billy4184

    Billy4184

    Joined:
    Jul 7, 2014
    Posts:
    5,791
    Is anyone else getting a situation where the horizontal mouse delta is roughly double the vertical?

    I simply accumulated the Mouse.current.delta.ReadValue() into a Vector2 and outputted in the Debug.Log. Then I added a circle to the UI to make sure I am measuring the same thing vertically and horizontally.

    If I go vertically up to the edge of the circle, I get a value of roughly (0, 70).
    If I go back to the center I get (0,0).
    If I go horizontally right to the edge of the circle I get roughly (140,0).
     
  3. tacman1123

    tacman1123

    Joined:
    Sep 14, 2020
    Posts:
    60
    After reading through this thread and hacking away, I'm still stuck.

    I feel like I must be missing something simple.

    Before

    Code (CSharp):
    1. private void Update() {  
    2.     Vector3 mouseMove = new Vector3(Input.GetAxis("Mouse X"), Input.GetAxis("Mouse Y"), 0);
    3.     // doSomething
    4. }
    After:

    Code (CSharp):
    1. public void OnMove(InputValue input)
    2. {
    3.    Vector2 inputVec = input.Get<Vector2>();
    4.    moveVec = new Vector3(inputVec.x, 0, inputVec.y
    );

    private void Update() {
    Vector3 mouseMove = moveVec; // ??
    }

    What should I be doing to convert from Input Manager to Input System?
     
  4. rroyermoraes

    rroyermoraes

    Joined:
    Oct 25, 2015
    Posts:
    5
    Ive tried the new input system a few months ago, and i gave up on the mouse problem, now months later the problem still persists, none of the solutions proposed here by other users or by unity staff solved the problem, even the demos included on the package have the same jittery behavior.
     
  5. AndrewChewie

    AndrewChewie

    Joined:
    Mar 23, 2015
    Posts:
    9
    Same problem here. v1.0.1 and mouse position is jittery. Is there any ETA for the fix? This critical problem been reported months ago and still not resolved, that's sad =(
     
  6. ilsvr

    ilsvr

    Joined:
    Jun 1, 2017
    Posts:
    12
    After reading this post I'm cancelling our conversion to the new input system. We rely on stable mouse positions and I don't see a way around this. I don't understand why multiple mouse move reports are received in a single frame, this seems pointless, at least without some way of signalling the final one. Does Mouse.current.position (which we would use at first), update several times a frame as well?
     
  7. TwentySicks

    TwentySicks

    Joined:
    Sep 6, 2012
    Posts:
    51
    I am also getting wierd behaviour with the Deltas, both mouse and pointer.

    Regarding accuracy, they both seem to go out of sync, if you mess to hard with it. Like swipe your fingers/mouse around eratically, it seems to really get bad. Only way to properly reset it, is to reload the scene or restart the application it seems.

    My main problem isnt the wonky accuracy, it's the fact that the Deltas dont reset to 0, as is described here;
    https://docs.unity3d.com/Packages/c...er.html#UnityEngine_InputSystem_Pointer_delta

    99.9% of the time they reset to + or - 1.0

    In my case, this leads to some objects im Translating according to the Delta to slowly "glide" in whatever direction the Vector resets to. I can Math.Clamp or If() my way out of the problem, but that makes it wonky in other ways.

    I recently started using unity again, and wanted to test out the new input system, but i must say, i would not recommend it. You will most certainly run into some issues with the deltas at least.
     
  8. Saucyminator

    Saucyminator

    Joined:
    Nov 23, 2015
    Posts:
    49
    These numbers seem to work good with the mouse (need to do more testing). But how do I only apply them if the user is using a mouse & keyboard? Using these values with gamepad makes it move very slow.
     
  9. n_gon

    n_gon

    Joined:
    Oct 8, 2020
    Posts:
    4
    So if you print "Event" at the beginning of your OnLook(InputValue val) function and you print "Update" on your Update() function you get like 8+ "Event"s for every 1 "Update".

    My assumption is that there is actually a game loop that fires faster than the Update() loop in C++ and when you Get<Vector2>() the value of Mouse.delta that tells it to "reset" delta back to zero and start accumulating again until you Get<Vector2>() it again. Can anyone confirm my assumptions are correct?

    If so, the only two proper ways to get the mouse input working properly with no stuttering would be to...
    1) On the event, accumulate a vector2 and clear it in LateUpdate. As long as your code requiring the delta is in Update() it should work. You may lose some accuracy if an update fires between Update() and LateUpdate(), if that's even possible. I don't know because I'm assuming there is a C++ gameloop and I'm unaware of how it fits in... This would be the "proper" way because it uses events which the new inputsystem seems to be based entirely on but it may have unnoticeable accuracy issues and is less efficient because you're accumulating values that are being accumulated for no reason...
    2) Just use the classic pooling method and ask what the Delta is in your actual Update() function... Kind of messy because you have to make manual code that is only relevant if the player is using a mouse but...

    edit: I just tried doing this to confirm if it is reset when you get the value and it is not. So I have no idea how the event resets itself...does it reset itself after the end of the event? When/how does delta go back to 0,0 and start accumulating again?

    val.Get<Vector2>();
    InputTurn += val.Get<Vector2>();

    edit2:
    I've done this and it causes extremely stuttery mouse movements especially when I set my turn speed/sensitivity high. I tried not using inputs and just set my "input" to a constant and it is extremely smooth - something weird is going on with Delta readings - it does not work.
     
    Last edited: Feb 12, 2021
  10. MJ_cb

    MJ_cb

    Joined:
    Jul 17, 2019
    Posts:
    1

    Do We Know If this has been fixed ? I have been looking everywhere and Mouse Position is doing exactly what you described here, it resets so quick that when I try to rotate a GameObject based on mouse position it twitches and unless I move the mouse "Blazing Fast" it won't be fast enough to rotate it. I am even questioning if I may be using the ActionsMap wrong ? I am attaching my script at the bottom just in case anyone wants to look at it, this works with the old input system so I know it has something to do with the events.

    Player Script --
    Code (CSharp):
    1. using System;
    2. using System.Collections;
    3. using System.Collections.Generic;
    4. using UnityEngine;
    5. using UnityEngine.InputSystem;
    6.  
    7.  
    8. public class Player : MonoBehaviour
    9. {
    10.     Rigidbody2D rigidbody;
    11.     public GameObject bulletPrefab;
    12.     public Transform bulletSpawn;
    13.  
    14.     public float movementSpeed = 2f;
    15.     float vertical;
    16.     float horizontal;
    17.     float rotationInputX;
    18.     float rotationInputY;
    19.  
    20.     Vector3 mousePosition;
    21.     Vector2 mousePos;
    22.  
    23.  
    24.     void Awake()
    25.     {
    26.         rigidbody = GetComponent<Rigidbody2D>();
    27.     }
    28.     // Start is called before the first frame update
    29.     void Start()
    30.     {
    31.      
    32.     }
    33.  
    34.     // Update is called once per frame
    35.     void Update()
    36.     {
    37.      
    38.         Vector2 moveDirection = Vector2.right * horizontal + Vector2.up * vertical;
    39.         rigidbody.position += Time.deltaTime * moveDirection * movementSpeed;
    40.         /*mousePos = Mouse.current.delta.ReadValue();
    41.         mousePos *= 1f;
    42.         Debug.Log($"Mouse Position {mousePos}");
    43.         */
    44.      
    45.  
    46.  
    47.  
    48.  
    49.  
    50.     }
    51.  
    52.     void FixedUpdate()
    53.     {
    54.         Vector2 worldPoint = Camera.main.ScreenToWorldPoint(mousePos);
    55.         Debug.Log($"world Point = {worldPoint}");
    56.         Vector2 difference = rigidbody.position - worldPoint;
    57.         Debug.Log($"Difference  = {difference}");
    58.        // difference.Normalize();
    59.         Debug.Log($"Normalized Difference  = {difference}");
    60.  
    61.         float desiredRotation = Mathf.Atan2(difference.y, difference.x) * Mathf.Rad2Deg;
    62.         transform.rotation = Quaternion.Euler(0f, 0f, desiredRotation + 90);
    63.  
    64.  
    65.     }
    66.  
    67.  
    68.  
    69.     public void OnMoveInput(float horizontal, float vertical)
    70.     {
    71.         this.vertical = vertical;
    72.         this.horizontal = horizontal;
    73.  
    74.     }
    75.     public void OnShootInput(float fireBtn)
    76.     {
    77.         float fireValue = fireBtn;
    78.         if(fireValue == 1)
    79.         {
    80.             Instantiate(bulletPrefab, bulletSpawn.position, bulletSpawn.rotation);
    81.         }
    82.     }
    83.  
    84.     public void OnRotationInput(float rotationInputX, float rotationInputY)
    85.     {
    86.         this.rotationInputX += rotationInputX;
    87.         this.rotationInputY += rotationInputY;
    88.  
    89.  
    90.  
    91.         // Rotation
    92.  
    93.         Vector3 worldPoint = Camera.main.ScreenToWorldPoint(new Vector2(rotationInputX, rotationInputY));
    94.         Debug.Log($"world Point = {worldPoint}");
    95.         Vector3 difference = new Vector3(this.rotationInputX, this.rotationInputY, 0) - worldPoint;
    96.         Debug.Log($"Difference  = {difference}");
    97.         difference.Normalize();
    98.         Debug.Log($"Normalized Difference  = {difference}");
    99.  
    100.         float desiredRotation = Mathf.Atan2(this.rotationInputX, this.rotationInputY) * Mathf.Rad2Deg;
    101.         transform.rotation = Quaternion.Euler(0f, 0f, desiredRotation + 90f);
    102.  
    103.     }
    104. }
    105.  
    InputHandler ---

    Code (CSharp):
    1. using System;
    2. using System.Collections;
    3. using System.Collections.Generic;
    4. using UnityEngine;
    5. using UnityEngine.InputSystem;
    6. using UnityEngine.Events;
    7.  
    8. [Serializable] public class MoveInputEvent : UnityEvent <float, float> { }
    9. [Serializable] public class ShootInputEvent : UnityEvent <float> { }
    10.  
    11. [Serializable] public class RotateInputEvent : UnityEvent <float, float> { }
    12.  
    13.  
    14. public class InputHandler : MonoBehaviour
    15. {
    16.     public MoveInputEvent moveInputEvent;
    17.     public ShootInputEvent shootInputEvent;
    18.     public RotateInputEvent rotateInputEvent;
    19.  
    20.     PlayerControls _controls;
    21.  
    22.     private void Awake()
    23.     {
    24.         _controls = new PlayerControls();
    25.     }
    26.     void OnEnable()
    27.     {
    28.         _controls.Player.Enable();
    29.         _controls.Player.Move.performed += OnMovePerformed;
    30.         _controls.Player.Move.canceled += OnMovePerformed;
    31.         _controls.Player.Fire.performed += OnShootPerformed;
    32.         //_controls.Player.Fire.canceled += OnShootPerformed;
    33.        _controls.Player.Look.performed += OnRotationPerformed;
    34.         //_controls.Player.Look.canceled += OnRotationPerformed;
    35.     }
    36.  
    37.     public void OnMovePerformed(InputAction.CallbackContext context)
    38.     {
    39.         Vector2 moveInput = context.ReadValue<Vector2>();
    40.         moveInputEvent.Invoke(moveInput.x, moveInput.y);
    41.         //Debug.Log($"Moving Input: {moveInput}");
    42.     }
    43.  
    44.     public void OnShootPerformed(InputAction.CallbackContext context)
    45.     {
    46.         float shootInput = context.ReadValue<float>();
    47.         shootInputEvent.Invoke(shootInput);
    48.  
    49.     }
    50.  
    51.     public void OnRotationPerformed(InputAction.CallbackContext context)
    52.     {
    53.      
    54.         Vector2 rotationInput = context.ReadValue<Vector2>();
    55.        /* rotationInput *= 0.5f;
    56.         rotationInput *= 0.1f;*/
    57.         Debug.Log($"rotationInput = {rotationInput.x} , {rotationInput.y}");
    58.         rotateInputEvent.Invoke(rotationInput.x, rotationInput.y);
    59.  
    60.  
    61.     }
    62. }
    63.  
     
  11. uwdlg

    uwdlg

    Joined:
    Jan 16, 2017
    Posts:
    61
    Not sure if I'm misunderstanding something (or something changed in the meantime), but from my understanding, the delta value should not be multiplied by Time.deltaTime to be framerate-independent.
    Here's my reasoning, assuming the mouse delta returns the accumulated movement relative to the mouse position in the previous frame: comparing for example 30fps and 60fps and assuming the mouse is moved at a constant speed, it would travel twice as far between two frames (two consecutive Update() calls) in the 30fps case than in the 60fps case. With 30fps I thus get a vector with double the magnitude of the one returned at 60fps. Using it to e.g. rotate the camera would consequently result in the same rotational offset after the same (real world) time.
    I tried this in a project using the new Input System to implement a mouse look mechanism after noticing the perceived mouse sensitivity change when capping the framerate at 30fps via
    Application.targetFramerate = 30;
    . Sure enough, I had multiplied the mouse delta value with Time.deltaTime and since removing it, I get the same rotational movement regardless of whether the framerate is capped or not.
     
    SolidAlloy likes this.
  12. Laumania

    Laumania

    Joined:
    Jun 27, 2012
    Posts:
    158
    I just tested it out in my game last night and you are right, it seems to work now, independent of framerate, even if not multiplied by Time.deltaTime.
    I\m very sure I have tested this too previously where it didn't worked like that - so I think they have fixed it somehow.
     
  13. Thasan

    Thasan

    Joined:
    Feb 22, 2018
    Posts:
    4
    I also had input jitter problem with mouse delta, so I made some tests and found that reducing my mouse polling rate has huge impact to jitter amount. On default my mouse polling rate it 1000hz, reducing to 500hz has no effect, reducing to 250hz has huge impact to jitter amount, but it's not totally gone. I had to reduce polling rate to 125hz and now my character can rotate smoothly.
    Also, getting rid of SetCallbacks() and my IInputActions interface was boosting performance a lot...

    Edit:
    Reading values on Update()

    Code (CSharp):
    1.     private void Update()
    2.     {
    3.         _lookVector = _defaultControls.FirstPerson.Look.ReadValue<Vector2>() * Time.deltaTime;
    4.         DebugGraph.Log("Old", _lookVector);
    5.     }
    6.  
    125hz

    1000hz
     
    Last edited: May 7, 2021
  14. Armageddon104

    Armageddon104

    Joined:
    Sep 14, 2014
    Posts:
    16
    I moved to the new input system and got super jittery mouse movement as described here. The two magic multiplier numbers fixed it, somewhat; it still jitters, and now that it's not going all over the place you can notice that vertical movement is faster than horizontal movement.

    This is really unacceptable. However it was being done before was fine and should at least be documented for porting ease, the two magic numbers are not enough.
     
unityunity