Search Unity

  1. Calling all beginners! Join the FPS Beginners Mods Challenge until December 13.
    Dismiss Notice
  2. It's Cyber Week at the Asset Store!
    Dismiss Notice

Mouse Delta Input

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

  1. caseyc

    caseyc

    Joined:
    Jul 2, 2012
    Posts:
    15
    I was checking out the new input system over the weekend, I'm a big fan so far of the features but I was wondering what the correct way to process the callback for mouse delta is.

    I've tried this:

    Code (CSharp):
    1.     private void Update()
    2.     {
    3.         transform.rotation = Quaternion.Euler(_rotation);
    4.     }
    5.  
    6.  
    7.     private void OnLook(InputAction.CallbackContext context)
    8.     {
    9.         Vector2 lookValue = context.ReadValue<Vector2>();
    10.  
    11.         _rotation.x += -lookValue.y * 0.022f * _sensitivity;
    12.         _rotation.y += lookValue.x * 0.022f * _sensitivity;
    13.     }
    And also this:

    Code (CSharp):
    1.     private void Update()
    2.     {
    3.         _rotation.x += -_lookValue.y * 0.022f * _sensitivity;
    4.         _rotation.y += _lookValue.x * 0.022f * _sensitivity;
    5.  
    6.         transform.rotation = Quaternion.Euler(_rotation);
    7.     }
    8.  
    9.  
    10.     private void OnLook(InputAction.CallbackContext context)
    11.     {
    12.         _lookValue = context.ReadValue<Vector2>();
    13.     }
    I have noticed that I receive several updates to the mouse delta per frame, so it seems like the first way is the correct manner to process the input. However, I was expecting this function to create a similar look speed to cs:go (0.022 is the constant m_yaw value in cs:go) and the second function seems to get closer to the expected result (although it is still a little faster). What units is the mouse delta returned in and what is the correct way to process it if I would want to create a similar sensitivity to source engine games? Thanks in advance for any help!
     
  2. Rene-Damm

    Rene-Damm

    Unity Technologies

    Joined:
    Sep 15, 2012
    Posts:
    858
    "delta" is in pixels, i.e. the amount of change on "position".

    Applying in Update() without taking time into account will essentially make rotation speeds dependent on framerate. To get constant speeds, scale by Time.deltaTime.
     
  3. caseyc

    caseyc

    Joined:
    Jul 2, 2012
    Posts:
    15
    For mouse movement wouldn't you want to take the raw change in pixels each frame though? I understand for a joystick you would want to get the direction the joystick is pointing and apply that by a rotation speed * deltaTime each frame but for a mouse you are measuring how far the user actually moved the mouse since the last update (or in this case the last time OnLook was called). For instance if the user was moving the mouse at at 10 inches/second on their mousepad and the mouse had a pixels per inch of 400 it would move 4000 pixels/second. If the framerate were 60 frames/sec it would be 4000/60 = 66.66 pixels per frame. If the framerate was 120 frames/sec it would be 4000/120 = 33.33 pixels per frame. In either case the overall speed of 4000 pixels/second is the same and not affected by the frame deltaTime. Unless I'm completely misunderstanding how this works lol. Thanks for you help!
     
    JimmyCushnie likes this.
  4. caseyc

    caseyc

    Joined:
    Jul 2, 2012
    Posts:
    15
    So I set up a quick test to see what was going on with the mouse delta being passed and now I'm even more confused than before.

    Code (CSharp):
    1.     private void Update()
    2.     {
    3.         Vector2 calculatedDelta = _mousePosition - _previousPosition;
    4.         _previousPosition = _mousePosition;
    5.  
    6.         if(_passedDelta != calculatedDelta)
    7.         {
    8.             Debug.Log("Passed Delta Mismatch: " + _passedDelta + ": " + calculatedDelta);
    9.         }
    10.  
    11.         if(_cumulativePassedDelta != calculatedDelta)
    12.         {
    13.             Debug.Log("Cumulative Passed Delta Mismatch: " + _cumulativePassedDelta + ": " + calculatedDelta);
    14.         }
    15.  
    16.         _cumulativePassedDelta = Vector2.zero;
    17.     }
    18.  
    19.  
    20.     private void OnLook(InputAction.CallbackContext context)
    21.     {
    22.         Vector2 delta = context.ReadValue<Vector2>();
    23.  
    24.         _passedDelta = delta;
    25.         _cumulativePassedDelta += delta;
    26.     }
    27.  
    28.     private void OnMousePositionChanged(InputAction.CallbackContext context)
    29.     {
    30.         _mousePosition = context.ReadValue<Vector2>();
    31.     }
    I basically set up a test where I calculate my own mouse delta manually using the mouse position, and compare it to the cumulative passed delta during a frame as well as the most recent passed delta in a frame. Neither the cumulative nor the raw passed delta seems to be accurate. The cumulative is way off, the passed one is closer but still off. What exactly is being passed with mouse delta?
     
  5. Rene-Damm

    Rene-Damm

    Unity Technologies

    Joined:
    Sep 15, 2012
    Posts:
    858
    There's some magic going on under the hood that makes things confusing for actions. Something that's still on the list to be looked at.

    In short, deltas will accumulate and reset automatically.

    Bear with me here... :)

    Let's say we get three deltas in a given frame. (1,1), (2,2), and (3,3). At the event level, this means that we get three events that have those exact deltas in them. At the state level (i.e. the memory that keeps the state of the mouse), however, we see accumulation. So after the *second* event the state is (3,3) and after the *third* event the state is (6,6). I.e. you get the accumulated mouse motion in the frame. And on the beginning of the next frame, it automatically resets to (0,0).

    This is done so that if you do Mouse.current.delta.ReadValue() in Update(), you don't just get the last delta of the last mouse event -- which could be (0,0) even though the frame actually did have mouse motion.

    However... for actions, this isn't what you'd expect. Actions observe every single state change. So what you expect is to get (1,1), (2,2) and (3,3) one after the other in the frame. What you actually get right now instead is (1,1),(3,3),(6,6). AND the action will observe the reset. I.e. you will *also* see (0,0) at the beginning of the next frame.

    This same problem crops up in other places, too, where something that does make sense for querying state in Update() or FixedUpdate() does not make sense for querying state in actions.

    What should probably happen is that Update() and FixedUpdate() see the accumulation happening but the actions do not. Something that still needs looking at.
     
  6. caseyc

    caseyc

    Joined:
    Jul 2, 2012
    Posts:
    15
    Thanks for the reply! I tried a similar test where I used Mouse.current.delta.ReadValue() in Update() but it was giving me the correct value with some framerates and not the correct one with others (i turned off vsync and was testing at about 2,000 fps vs capping to 30 to see if there was a difference). I tried playing with the input system update mode to correct this but it didn't seem to affect it at all. I suspect that the mouse delta isn't getting reset each frame but is being reset at some other point in time but I can't quite tell when. I'm on 2018.3.9 if that makes any difference. Thanks again!
     
  7. Elhimp

    Elhimp

    Joined:
    Jan 6, 2013
    Posts:
    20
    I'm not mathematician, but this look quite opposite to definition of delta. Anyway...

    So, is it gonna be benefitial to have some InputAction("name", "<Mouse>/delta")* with multiple callbacks per frame, which I should ignore completely? Or it vould be better to just "manually" calculate difference between previous and current cursor positions in scope of preffered update rate, or just read lates value from Mouse.current.delta?

    *considering I don't need to make composite action of multiple Vector2 sources.
     
  8. Wokky

    Wokky

    Joined:
    Apr 3, 2014
    Posts:
    5
    This seems similar to an issue I encountered after experimenting with converting a first-person character controller over to the new input system. Mouse input became jittery and felt out-of-sync with my mouse movements. After finding this thread I tried changing from using an action callback to
    Mouse.current.delta.ReadValue()
    but it doesn't appear to have resolved the problem.



    This toy example roughly illustrates what I'm observing - the position of the orange square is being offset in Update() via the old input system with
    Input.GetAxisRaw()
    while the blue is offset by
    Mouse.current.delta.ReadValue()


    Where the acceleration of the orange square generally matches that of the cursor, the blue square seems to unpredictably lag or jump ahead. The second half of the video also demonstrates its movement becoming out of sync: dragging the cursor from a point and eventually returning to that same point means that the orange square also returns to its initial position as expected, but the blue square comes to rest in a different location.
     
    Last edited: Jul 18, 2019
  9. Sonorpearl

    Sonorpearl

    Joined:
    Sep 8, 2017
    Posts:
    32
    @Rene-Damm It would be nice to get an Update for the problem, which is shown in the video from @Wokky.
    It´s an essential feature, which shouldn't be broken for long. ^^
     
    JimmyCushnie likes this.
  10. Marble

    Marble

    Joined:
    Aug 29, 2005
    Posts:
    1,212
    I just ran into this myself. Is there intent to make frame by frame delta input more usable in actions?
     
    Last edited: Sep 28, 2019
  11. Laumania

    Laumania

    Joined:
    Jun 27, 2012
    Posts:
    130
    I'm listening here too...and my mouse is now behaving a little wierd I think in my FPS controller.
     
  12. Laumania

    Laumania

    Joined:
    Jun 27, 2012
    Posts:
    130
    @Rene-Damm Any update to this issue? Or work arounds? Seems like a pretty big thing not working properly, as "mouse" is kind of a populate controller for games :)
     
    JimmyCushnie likes this.
  13. Laumania

    Laumania

    Joined:
    Jun 27, 2012
    Posts:
    130
    By the way, I'm not using mouse input as events, I'm polling and still it works very wierd and not at all like the old input. It's clearly depending on the DPI/Resolution or something like that, which is not ideal.

    Code (CSharp):
    1. private void Update()
    2. {
    3. LookDelta  = _defaultControls.Player.Look.ReadValue<Vector2>() * Time.deltaTime;
    4. }
     
  14. Rene-Damm

    Rene-Damm

    Unity Technologies

    Joined:
    Sep 15, 2012
    Posts:
    858
    Hey guys, sorry for the huge lag here.

    @Wokky Could you file a ticket with the Unity bug reporter using that setup you have there? Would like to take a closer look at that.

    I did some quick some testing and even trying to account for the various scaling/alterations that the old input manager applies (even if you do GetAxisRaw), while I see a difference in magnitude, I don't see grave differences in behavior. Still, we've seen enough reports about wonky behavior with mouse delta input to warrant a close examination.

    upload_2019-10-8_18-20-54.png

    As far as actions bound to deltas are concerned, I'm not sure yet how to most elegantly solve that. Problem is most often it *does* make most sense to tap the accumulated delta (such as when you do a polled ReadValue in Update or when you just store the latest value in an action callback) but sometimes it doesn't (such as when you really just want motion updates one by one). One potential way of solving it is having two controls for each delta-style control (i.e. position and scroll deltas): one that accumulates and one that doesn't. Then in bindings, one can decide which to tap.

    Just to note that, in the old input system, you *always* get an accumulated value. I.e. "Mouse X" and "Mouse Y" are always accumulated frame to frame. (at least on Windows; haven't checked the myriads of other platforms)

    ////EDIT: Just for reference, this is the test script I used above. (relying on Squiggle for graphing)

    Code (CSharp):
    1. public class MouseDeltaTest : MonoBehaviour
    2. {
    3.     private InputAction m_Action;
    4.  
    5.     void Start()
    6.     {
    7.         m_Action = new InputAction(type: InputActionType.Value, binding: "<Mouse>/delta");
    8.         m_Action.Enable();
    9.     }
    10.  
    11.     void Update()
    12.     {
    13.         var vertical = Input.GetAxis("Mouse Y");
    14.         var horizontal = Input.GetAxis("Mouse X");
    15.         var delta = m_Action.ReadValue<Vector2>();
    16.  
    17.         // Account for scaling applied directly in Windows code by old input system.
    18.         delta *= 0.5f;
    19.  
    20.         // Account for sensitivity setting on old Mouse X and Y axes.
    21.         delta *= 0.1f;
    22.  
    23.         DebugGraph.Log("Old", new Vector2(horizontal, vertical));
    24.         DebugGraph.Log("New", delta);
    25.     }
    26. }
    27.  
     
    JimmyCushnie likes this.
  15. Laumania

    Laumania

    Joined:
    Jun 27, 2012
    Posts:
    130
    @Rene-Damm Well, the reason you might not see an issue is because you have multiplying with these magic numbers? :D

    Code (CSharp):
    1. // Account for scaling applied directly in Windows code by old input system.
    2.         delta *= 0.5f;
    3.         // Account for sensitivity setting on old Mouse X and Y axes.
    4.         delta *= 0.1f;

    I was just creating a demo project, when I discovered that my problem was a combination of two things:

    1. I were missing your magic values
    2. I were, for some reason, multiplying by Time.deltaTime.

    Multiplying by magic values and removing the Time.deltaTime solved my issue it seems.


    Code (CSharp):
    1.  var lookDeltaRaw = _defaultControls.Player.Look.ReadValue<Vector2>();
    2.                
    3.                 // Account for scaling applied directly in Windows code by old input system.
    4.                 lookDeltaRaw *= 0.5f;
    5.                
    6.                 // Account for sensitivity setting on old Mouse X and Y axes.
    7.                 lookDeltaRaw *= 0.1f;
    8.  
    9.                 return lookDeltaRaw;
     
  16. Laumania

    Laumania

    Joined:
    Jun 27, 2012
    Posts:
    130
    ...and after that I actually ended up removing the "magic values" and just adjust my sensitivity on my FirstPersonController to fit.

    Seems to work...so right now it looks like my mistake was to * Time.deltaTime...just if others get here too with same wierd behavior.
     
  17. Rene-Damm

    Rene-Damm

    Unity Technologies

    Joined:
    Sep 15, 2012
    Posts:
    858
    @Laumania If the problem is scaling of values, that'll be easy to correct e.g. by applying processors. We can certainly tweak that on the managed side. ATM the deltas are served pretty much raw from the platform.

    However, problems like the one illustrated by @Wokky seem to go deeper and hint at differences of deltas not just in magnitude but in distribution over time. If that is indeed the case, scaling alone unfortunately won't do the trick.
     
  18. Laumania

    Laumania

    Joined:
    Jun 27, 2012
    Posts:
    130
    Yeah I actually know about the scale, but didn't added that, just adjusted sensitivity. But as it's down to 0,2 for me right now...I might want to apply some scale, to have a better range of sensitivity ingame.

    At least I don't have an issue anymore with the mouse input in the new input system. I'll let you know if I run into problems :)
     
  19. camirving

    camirving

    Joined:
    Jan 20, 2014
    Posts:
    34
    Soo, any updates from this? It still feels off.
     
  20. Laumania

    Laumania

    Joined:
    Jun 27, 2012
    Posts:
    130
    Well, I ended up getting my to work fine. Feels as it use to.

    Can you share code, maybe we can spot the issue?
     
  21. Hellzbellz123

    Hellzbellz123

    Joined:
    May 15, 2019
    Posts:
    12
    so ive been trying to setup a camera controller and the delta doesnt seem to get reset to 0 when you stop moving the mouse. am i missing something here?
     
  22. Jichaels

    Jichaels

    Joined:
    Dec 27, 2018
    Posts:
    137
    You're probably not polling the action, and using only callbacks. Try polling for movement/camera, it's much better and easier
     
  23. Hellzbellz123

    Hellzbellz123

    Joined:
    May 15, 2019
    Posts:
    12
    polling is if statements right? how would i even do something like that. sorry if its a super noob thing
     
  24. Jichaels

    Jichaels

    Joined:
    Dec 27, 2018
    Posts:
    137
    No it's not, you just get a reference of one of your action (let's say Movement) using a sfield

    Code (CSharp):
    1. [SerializedField] private InputActionReference _inputActionReferenceMovement;
    2. private Vector2 _inputMovement;
    Then in your update method :

    Code (CSharp):
    1. _inputMovement = inputActionReferenceMovement.action.ReadValue<Vector2>();
    2.  
    3. // now use _inputMovement
     
  25. Laumania

    Laumania

    Joined:
    Jun 27, 2012
    Posts:
    130
    This is work in progress and this InputManager change all the time, but this is how it looks right now. I already know I need to simplify it.

    This solves more than just your mouse challenge, but might be interested to see either way.

    I wanted to have all my actual handling of input in one place, the InputManager, and then i trigger custon events, set properties etc on that one, so that all my other scripts just use this InputManager to get there data.
    This way, it easier to change from old input to the new input system, and in the future to the new new input system, when that hits at some point :)

    Anyway, this works good for me and for your look, it's the LookDelta property you need to look at.

    Code (CSharp):
    1. public class InputManager : MonoBehaviour
    2.     {
    3.         private DefaultControls     _defaultControls;
    4.         private static InputManager _instance;
    5.         private InputContext        _currentInputContext;
    6.  
    7.         [HideInInspector]
    8.         public UnityEvent OnHideUITriggered;
    9.         [HideInInspector]
    10.         public UnityEvent OnInventoryButtonTriggered;
    11.         [HideInInspector]
    12.         public ItemSlotTriggeredEvent OnItemSlotButtonTriggered;
    13.  
    14.         private void Awake()
    15.         {
    16.             if (_instance != null && _instance != this)
    17.             {
    18.                 Destroy(this.gameObject);
    19.             }
    20.             else
    21.             {
    22.                 _instance = this;
    23.             }
    24.  
    25.             _defaultControls = new DefaultControls();
    26.         }
    27.  
    28.         private void Start()
    29.         {
    30.             SetContext(InputContext.GamePlay);
    31.  
    32.             _defaultControls.Player.Enable();
    33.             _defaultControls.UI.Enable();
    34.  
    35.             _defaultControls.Player.Running.performed         += (ctx) => IsRunning = true;
    36.             _defaultControls.Player.Running.canceled          += (ctx) => IsRunning = false;
    37.  
    38.             _defaultControls.Player.PrimaryAction.performed   += (ctx) => PrimaryActionPressed = true;
    39.             _defaultControls.Player.PrimaryAction.canceled    += (ctx) => PrimaryActionPressed = false;
    40.  
    41.             _defaultControls.Player.SecondaryAction.performed += (ctx) => SecondaryActionPressed = true;
    42.             _defaultControls.Player.SecondaryAction.canceled  += (ctx) => SecondaryActionPressed = false;
    43.  
    44.             _defaultControls.Player.RotateSnap.performed      += (ctx) => RotateSnapPressed = true;
    45.             _defaultControls.Player.RotateSnap.canceled       += (ctx) =>
    46.             {
    47.                 RotateSnapPressed   = false;
    48.                 RotateSnapCanceled  = true;
    49.             };
    50.            
    51.             _defaultControls.Player.RotateAction.performed  += (ctx) =>
    52.             {
    53.                 RotateActionPressed = true;
    54.                
    55.                 //Todo: Should be handled by input context/states?
    56.                 _defaultControls.Player.Look.Disable();
    57.             };
    58.             _defaultControls.Player.RotateAction.canceled += (ctx) =>
    59.             {
    60.                 RotateActionPressed = false;
    61.  
    62.                 //Todo: Should be handled by input context/states?
    63.                 _defaultControls.Player.Look.Enable();
    64.             };
    65.  
    66.             _defaultControls.UI.HideHUD.performed += (ctx) =>
    67.             {
    68.                 if (OnHideUITriggered != null)
    69.                     OnHideUITriggered.Invoke();
    70.             };
    71.  
    72.             _defaultControls.Player.Inventory.performed += (ctx) =>
    73.             {
    74.                 if (OnInventoryButtonTriggered != null)
    75.                     OnInventoryButtonTriggered.Invoke();
    76.             };
    77.  
    78.             _defaultControls.Player.ItemSlot01.performed += (ctx) => ExecuteOnItemSlotButtonTriggered(1);
    79.             _defaultControls.Player.ItemSlot02.performed += (ctx) => ExecuteOnItemSlotButtonTriggered(2);
    80.             _defaultControls.Player.ItemSlot03.performed += (ctx) => ExecuteOnItemSlotButtonTriggered(3);
    81.         }
    82.  
    83.         private void ExecuteOnItemSlotButtonTriggered(int itemSlotIndex)
    84.         {
    85.             if (OnItemSlotButtonTriggered != null)
    86.                 OnItemSlotButtonTriggered.Invoke(itemSlotIndex);
    87.         }
    88.  
    89.         public void SetContext(InputContext context)
    90.         {
    91.             _currentInputContext = context;
    92.             //Debug.Log($"Set UIContext = '{context}'");
    93.  
    94.             switch (_currentInputContext)
    95.             {
    96.                 case InputContext.GamePlay:
    97.                     _defaultControls.Player.Enable();
    98.                     _defaultControls.UI.Enable();
    99.                     SetCursorLocked(true);
    100.                     break;
    101.                 case InputContext.GameMenu:
    102.                     _defaultControls.Player.Disable();
    103.                     _defaultControls.UI.Disable();
    104.                     SetCursorLocked(false);
    105.                     break;
    106.                 case InputContext.GameInventory:
    107.                     _defaultControls.Player.Disable();
    108.                     _defaultControls.UI.Disable();
    109.                     _defaultControls.Player.Movement.Enable();
    110.                     _defaultControls.Player.Inventory.Enable();
    111.                     SetCursorLocked(false);
    112.                     break;
    113.                 default:
    114.                     Debug.LogError($"Unknown InputContext: '{_currentInputContext}'");
    115.                     break;
    116.             }
    117.         }
    118.  
    119.         private void SetCursorLocked(bool isLocked)
    120.         {
    121.             Cursor.lockState    = isLocked ? CursorLockMode.Locked : CursorLockMode.None;
    122.             Cursor.visible      = isLocked ? false : true;
    123.         }
    124.  
    125.         private void FixedUpdate()
    126.         {
    127.             Movement    = _defaultControls.Player.Movement.ReadValue<Vector2>();
    128.         }
    129.  
    130.         private void Update()
    131.         {
    132.             LookDelta                   = _defaultControls.Player.Look.ReadValue<Vector2>();
    133.             RotateAxisDelta             = _defaultControls.Player.RotateAxis.ReadValue<Vector2>();          
    134.             Jump                        = _defaultControls.Player.Jump.triggered;
    135.             InteractButtonUp            = _defaultControls.Player.Interact.triggered;
    136.             SecondaryActionTriggered    = _defaultControls.Player.SecondaryAction.triggered;
    137.             RotateActionTriggered       = _defaultControls.Player.RotateAction.triggered;
    138.             RotateSnapTriggered         = _defaultControls.Player.RotateSnap.triggered;
    139.             GrabDistance                = _defaultControls.Player.GrabDistance.ReadValue<float>();
    140.  
    141.             UIBackButtonTriggered       = _defaultControls.UI.Back.triggered;
    142.         }
    143.         private void LateUpdate()
    144.         {
    145.             //Reset
    146.             RotateSnapCanceled = false;
    147.         }
    148.  
    149.         public static InputManager Instance     { get { return _instance; } }
    150.         public InputContext CurrentContext      { get { return _currentInputContext; } }
    151.  
    152.         public Vector2 LookDelta                { get; private set; } = new Vector2(0.5f, 0.5f);
    153.         public Vector2 Movement                 { get; private set; } = Vector2.zero;
    154.         public bool IsRunning                   { get; private set; } = false;
    155.         public bool Jump                        { get; private set; } = false;
    156.         public bool InteractButtonUp            { get; private set; } = false;
    157.         public bool PrimaryActionPressed        { get; private set; } = false;
    158.         public bool SecondaryActionPressed      { get; private set; } = false;
    159.         public bool SecondaryActionTriggered    { get; private set; } = false;
    160.         public bool RotateActionPressed         { get; private set; } = false;
    161.         public bool RotateActionTriggered       { get; private set; } = false;
    162.         public bool RotateSnapTriggered         { get; private set; } = false;
    163.         public bool RotateSnapPressed           { get; private set; } = false;
    164.         public bool RotateSnapCanceled          { get; private set; } = false;
    165.         public Vector2 RotateAxisDelta          { get; private set; } = Vector2.zero;
    166.         public float GrabDistance               { get; private set; } = 0f;
    167.  
    168.         public bool UIBackButtonTriggered       { get; private set; } = false;
    169.     }
    170.  
    171.     [System.Serializable]
    172.     public class ItemSlotTriggeredEvent : UnityEvent<int>
    173.     {
    174.     }
    175.  
    176.     public enum InputContext
    177.     {
    178.         GamePlay = 1,
    179.         GameMenu = 2,
    180.         GameInventory = 3
    181.     }
     
  26. Hellzbellz123

    Hellzbellz123

    Joined:
    May 15, 2019
    Posts:
    12
    this was written before i saw above post
    Code (CSharp):
    1. using Cinemachine;
    2. using System.Collections;
    3. using System.Collections.Generic;
    4. using UnityEngine;
    5. using UnityEngine.InputSystem;
    6. using UnityEngine.InputSystem.Controls;
    7. using VanillaCoffee;
    8.  
    9. public class InputManager : MonoBehaviour
    10. {
    11.     [SerializeField] private InputActionReference _inputActionReferenceAiming;
    12.     public InputAction AimingAction;
    13.  
    14.     Vector2 look;
    15.     private Vector2 _inputAim;
    16.  
    17.     void Start() => CinemachineCore.GetInputAxis = GetAxisCustom;
    18.  
    19.     private void OnEnable()
    20.     {
    21.         {
    22.             _inputActionReferenceAiming.action.performed += ctx => look = ctx.ReadValue<Vector2>();
    23.             _inputActionReferenceAiming.action.Enable();
    24.         }
    25.  
    26.     }
    27.  
    28.     private void OnDisable()
    29.     {
    30.         _inputActionReferenceAiming.action.performed -= ctx => look = Vector2.zero;
    31.         _inputActionReferenceAiming.action.Disable();
    32.     }
    33.  
    34.  
    35.     public float GetAxisCustom(string axisName)
    36.     {
    37.         //Log();
    38.         _inputAim = _inputActionReferenceAiming.action.ReadValue<Vector2>();
    39.  
    40.         look = _inputAim;
    41.  
    42.         if (axisName == "Mouse X")
    43.         {
    44.             return look.x;
    45.         }
    46.  
    47.         else if (axisName == "Mouse Y")
    48.         {
    49.             return look.y;
    50.         }
    51.         return 0;
    52.     }
    53.  
    54.     void Log()
    55.     {
    56.         string lookdir = look.ToString();
    57.  
    58.         Debug.Log(lookdir); //
    59.     }
    60. }
    this is all ive managed to piece together but now im not getting any input
    this was written before i saw above post
     
    Last edited: Oct 22, 2019
  27. Jichaels

    Jichaels

    Joined:
    Dec 27, 2018
    Posts:
    137
    If you're polling, you don't need to assign callbacks to OnEnable/OnDisable, simply remove all that part. Look isn't usefull anymore, you're just copying a vector2 to a vector2
     
  28. Laumania

    Laumania

    Joined:
    Jun 27, 2012
    Posts:
    130
    Yeah try and look at my sample and take out only the things you need and post what you end up with. Try and do it in a similar manner as I am doing. Then when you get it working, then you refactor if you want to some other way.

    The trick it to try and keep things as simple as possible, which is also the hardest thing to do :)
     
  29. camirving

    camirving

    Joined:
    Jan 20, 2014
    Posts:
    34
    polling mouse delta is still wrong for me.

    by using the good old "Input.GetAxisRaw("Mouse X")"/MouseY and creating a Vector2 with those values, I get a far smoother experience than by polling mouse delta with the new input system.

    I am not using callbacks; I am polling values straight from the action.

    I am creating a first person shooter; the new system does not work properly with very suble movements.

    If I move my mouse veeeeery slowly, it does not pick up any delta at all but the old system works just fine.

    Mouse delta is broken.
     
  30. Hellzbellz123

    Hellzbellz123

    Joined:
    May 15, 2019
    Posts:
    12
    you might try using mouse position to do small movements
    and then switching?
     
  31. Jichaels

    Jichaels

    Joined:
    Dec 27, 2018
    Posts:
    137

    Mmmh that's not the case for me (and mind you, I'm at 400dpi on desktop). Even the slightest movement is getting picked up. Maybe you're doing something wrong ?

    What I'm using :

    Code (CSharp):
    1. _inputRotation = inputActionCameraRotation.action.ReadValue<Vector2>();
    2.  
    3. if (_currentControlScheme == CustomControlScheme.MouseKeyboard)
    4. {            
    5.     _inputRotation *= Rules.RotationSpeedMouse;
    6. }
    7. else if (_currentControlScheme == CustomControlScheme.Gamepad)
    8. {
    9.     if (Mathf.Abs(_inputRotation.x) < Rules.JoystickDeadZone && Mathf.Abs(_inputRotation.y) < Rules.JoystickDeadZone) return;
    10.     _inputRotation *= Time.deltaTime * Rules.RotationSpeedJoystick;
    11. }
    12. _transform.Rotate(Vector3.up, _inputRotation.x);
    13. _currentLocalRotationEulers.x = Mathf.Clamp(_currentLocalRotationEulers.x - _inputRotation.y, -80, 80);
    14. HeadSet.CameraTransform.localEulerAngles = _currentLocalRotationEulers;
    And it just works fine !
     
  32. camirving

    camirving

    Joined:
    Jan 20, 2014
    Posts:
    34
    I must be doing something wrong then. I'll double check.
     
  33. Hellzbellz123

    Hellzbellz123

    Joined:
    May 15, 2019
    Posts:
    12
    so im still having issues with this damn system however it seems to be just how the mouse gets handled. would you mind showing me the settings you are using inside the Input ACtions file thingy?


    I FIGURED IT OUT THAT TOOK WAY TOO LONG HOLY CRAP.

    for anyone else who has this issue
    mouse delta input needs too come from a action type: Value, Control Type: Vector 2
     

    Attached Files:

    Last edited: Oct 25, 2019
  34. Jichaels

    Jichaels

    Joined:
    Dec 27, 2018
    Posts:
    137
    Action is Value / Vector2. The binding is Delta [Mouse]. Nothing else
     
  35. Laumania

    Laumania

    Joined:
    Jun 27, 2012
    Posts:
    130
    Great you solved it! What did you set it to before where it didn't work?
     
  36. Hellzbellz123

    Hellzbellz123

    Joined:
    May 15, 2019
    Posts:
    12
    anything other than what it was set too i even tried value at first but it wasnt set to vector2 i set it to axis and something else
     
  37. deeprest

    deeprest

    Joined:
    Jun 8, 2016
    Posts:
    5
    On MacOS, values are generated for the mouse delta while the cursor is motionless. I've submitted a bug report, FogBugz ticket here.

    MacbookPro macOS 10.13.6
    Unity 2019.2.6f1
    Input System 1.0.0 preview.1

    Here's a horribly-made demonstration. The red timer resets when the mouse delta is non-zero.


    Here the code for the test
    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4. using UnityEngine.InputSystem;
    5. using UnityEngine.UI;
    6.  
    7. // Bug: intermittent. Mouse delta sometimes has non-zero values while mouse is not moving, apparent only when clicking.
    8. // To reproduce: move cursor then keep cursor motionless. Then click and observe debug logs generated
    9. // because mouse delta is non-zero. May take a few tries before bug is apparent.
    10.  
    11. public class bug : MonoBehaviour
    12. {
    13.   Controls Controls;
    14.   public Vector2 currentDelta;
    15.   public Vector2 readValue;
    16.  
    17.   public Text delta;
    18.   public Text deltaNow;
    19.   public Text value;
    20.   public Text valueNow;
    21.   public Text timeSinceLastNonZero;
    22.  
    23.   private void Start()
    24.   {
    25.     Controls = new Controls();
    26.     Controls.Enable();
    27.     Controls.BipedActions.Enable();
    28.   }
    29.  
    30.   float timeNonZero;
    31.  
    32.   void Update()
    33.   {
    34.     currentDelta = Mouse.current.delta.ReadValue();
    35.     if( currentDelta.magnitude > 0.0f )
    36.     {
    37.       timeNonZero = Time.time;
    38.       Debug.LogFormat( "Last nonzero Mouse.current.delta {0} {1}", currentDelta.x, currentDelta.y );
    39.       delta.text = "Last nonzero delta " + currentDelta.x + " " + currentDelta.y;
    40.     }
    41.     deltaNow.text = "Current delta " + currentDelta.x + " " + currentDelta.y;
    42.  
    43.     readValue = Controls.BipedActions.Aim.ReadValue<Vector2>();
    44.     if( readValue.magnitude > 0.0f )
    45.     {
    46.       timeNonZero = Time.time;
    47.       Debug.LogFormat( "Last nonzero ReadValue<Vector2>() {0} {1}", readValue.x, readValue.y );
    48.       value.text = "Last nonzero ReadValue<Vector2>() " + readValue.x + " " + readValue.y;
    49.     }
    50.     valueNow.text = "Last nonzero ReadValue<Vector2>() " + readValue.x + " " + readValue.y;
    51.  
    52.     timeSinceLastNonZero.text = (Time.time - timeNonZero).ToString();
    53.   }
    54. }
    55.  
    Same result if use Mouse.current.delta or read the value from an Action.

    Here's what it looks like in my game
     
  38. Saucyminator

    Saucyminator

    Joined:
    Nov 23, 2015
    Posts:
    23
    I'm also having trouble upgrading to the new input system where I used to have Input.GetAxis("Mouse X") (and Y), and now trying to read the mouse delta.

    I've setup a Mouse action to "action type: Value, control type: Vector2" and the binding is using the path "Delta [Mouse]".

    New system is very jittery and I cannot replicate the same movement for my weapon sway.

    Code (CSharp):
    1. using UnityEngine;
    2.  
    3. public class Sway : MonoBehaviour {
    4.   [SerializeField] private bool useNewInputs = true;
    5.   [SerializeField] private float swayAmount = 0.02f;
    6.   [SerializeField] private float maxSwayAmount = 0.06f;
    7.   [SerializeField] private float swaySmoothValue = 4f;
    8.  
    9.   private Vector3 initialSwayPosition;
    10.   private InputMaster inputs;
    11.   private Vector2 mouse;
    12.  
    13.   private void Awake () {
    14.     inputs = new InputMaster();
    15.   }
    16.  
    17.   private void OnEnable () {
    18.     inputs.Weapon.Mouse.Enable();
    19.   }
    20.  
    21.   private void OnDisable () {
    22.     inputs.Weapon.Mouse.Disable();
    23.   }
    24.  
    25.   private void Start () {
    26.     initialSwayPosition = transform.localPosition;
    27.   }
    28.  
    29.   private void LateUpdate () {
    30.     mouse = inputs.Weapon.Mouse.ReadValue<Vector2>();
    31.  
    32.     float movementX = (useNewInputs) ? -mouse.x * swayAmount : -Input.GetAxis("Mouse X") * swayAmount;
    33.     float movementY = (useNewInputs) ? -mouse.y * swayAmount : -Input.GetAxis("Mouse Y") * swayAmount;
    34.  
    35.     movementX = Mathf.Clamp(movementX, -maxSwayAmount, maxSwayAmount);
    36.     movementY = Mathf.Clamp(movementY, -maxSwayAmount, maxSwayAmount);
    37.  
    38.     Vector3 finalSwayPosition = new Vector3(movementX, movementY, 0f);
    39.     transform.localPosition = Vector3.Lerp(transform.localPosition, finalSwayPosition + initialSwayPosition, Time.deltaTime * swaySmoothValue);
    40.   }
    41. }
    42.  
    Album with two GIFs showing old and new input system:
    https://imgur.com/a/cLCF1tH
     
    JimmyCushnie likes this.