Search Unity

input.getkeydown but in the new input system?

Discussion in 'Input System' started by Rajivrocks, Nov 4, 2020.

  1. Rajivrocks

    Rajivrocks

    Joined:
    Oct 3, 2019
    Posts:
    15
    Hi, I'm trying to get the behaviour of the GetKeyDown method of the legacy input system. This behaviour would look something like. I hold down the space bar for 5 seconds and release it. if I were to log this action you'd see only 1 log appear that says something among the lines of "space pressed".

    With the new input system when i configure a new action called "ScreenCycleLeft" with properties "Pass through -> Button" and attach a binding to this action that listens to the "A" key on the keyboard I don't get the same behaviour :(

    When I do this and log the keypress it gets triggered as long as I hold the key down. I don't want this. When I were to hold down the key I'd like to still see one log in my console saying something like "a pressed", That's it. i tried changing the interaction to "Press" but would just keep the "a" button pressed even if I let go.

    Here is my code on how I handle the keypresses, maybe I'm doing something wrong
    The issue is concering lines 19 to 52

    Code (CSharp):
    1. //how I define my controls
    2. controls.Hacker.ScreenCycleRight.performed += ctx => _kbRight = ctx.ReadValue<float>();
    3.         controls.Hacker.ScreenCycleLeft.performed += ctx => _kbLeft = ctx.ReadValue<float>();
    4.  
    5. // my function
    6. private void ScreenFocusCheck()
    7.     {
    8.         // If you are zoomed in on the screen check if you are pressing esc, if so, go to the original camera position and set the bool on flase.
    9.         if (_isZoomedIn)
    10.         {
    11.             //Exit zoom in state
    12.             if (_kbEsc == 1f)
    13.             {
    14.                 transform.position = _hackerStartPos;
    15.                 _isRotating = true;
    16.                 Debug.Log(_kbEsc);
    17.                 _isZoomedIn = false;
    18.             }
    19.             //Screen switching
    20.             if (_kbRight == 1f && _currentPos == 2)
    21.             {
    22.                 _currentPos = 0;
    23.                 transform.position = _screenList[_currentPos].GetChild(1).transform.position;
    24.                 transform.LookAt(_screenList[_currentPos].position);
    25.                 //Debug.Log("SecurityCams " + _currentPos);
    26.                 Debug.Log(_kbRight);
    27.             }
    28.             else if (_kbRight == 1f)
    29.             {
    30.                 transform.position = _screenList[_currentPos + 1].GetChild(1).transform.position;
    31.                 transform.LookAt(_screenList[_currentPos + 1].position);
    32.                 _currentPos += 1;
    33.                 //Debug.Log("right " + _currentPos);
    34.                 Debug.Log(_kbRight);
    35.             }
    36.             if (_kbLeft == 1f && _currentPos == 0)
    37.             {
    38.                 _currentPos = 2;
    39.                 transform.position = _screenList[_currentPos].GetChild(1).transform.position;
    40.                 transform.LookAt(_screenList[_currentPos].position);
    41.                 //Debug.Log("Floorplan " + _currentPos);
    42.                 Debug.Log(_kbLeft);
    43.             }
    44.             else if (_kbLeft == 1f)
    45.             {
    46.                 transform.position = _screenList[_currentPos - 1].GetChild(1).transform.position;
    47.                 transform.LookAt(_screenList[_currentPos - 1].position);
    48.                 _currentPos -= 1;
    49.                 //Debug.Log("Left " + _currentPos);
    50.                 Debug.Log(_kbLeft);
    51.             }
    52.         }
    53.         else
    54.         {
    55.             //check if you are clicking the left mouse button, if this is true and the raycast is colliding with the the object with tag "Screen"
    56.             // set the bool on true and teleport the camera to the zoomed in position
    57.             if (_mouseLeftClick == 1f)
    58.             {
    59.                 var ray = Camera.main.ScreenPointToRay(_mousePosition);
    60.                 if (Physics.Raycast(ray, out RaycastHit hit))
    61.                 {
    62.                     if (hit.transform.CompareTag("Screen"))
    63.                     {
    64.                         _isZoomedIn = true;
    65.                         _isRotating = false;
    66.  
    67.                         _currentPos = _screenList.FindIndex(x => x == hit.transform);
    68.                         _zoomObject = hit.transform.GetChild(1);
    69.                         transform.position = _zoomObject.transform.position;
    70.                         transform.LookAt(hit.transform);
    71.                     }
    72.                 }
    73.             }
    74.         }
    75.     }
    The code might seem messy but the logic works I've tested it. the only thing that is bugging me is that whatever key I press will get called multiple times unless I press the key extremely quick which I can barely do at the best of times.

    I used to do this with a switch case because I had a 1d axis with the left and right arrow keys. But thinking that was the issue I made this contraption.

    If anyone can help me get the GetKeyDown behaviour from the legacy input system in the new input system i'd be so happy!
    And yes, this functio nis called in Update()
     
  2. Rajivrocks

    Rajivrocks

    Joined:
    Oct 3, 2019
    Posts:
    15
    Okay, so i found a janky way to do it reading this thread on the unity forums: https://forum.unity.com/threads/how...n-situaiton-with-the-new-input-system.627184/ I configured my two buttons like this: went to my action -> binding for the "a" and "d" key. added an interaction "Press".
    Unity getkeydown forumpost.png

    after that in the if statements where i compared the floats of for example _kbRIght == 1f I now compare
    Code (CSharp):
    1. controls.Hacker.ScreenCycleLeft.triggered
    Now when I run my scene it neatly cycles through the screens and won't skip 3-4 items because it registers a keypress everytime.

    If there is a much better way (i'm 100% there is) please still answer this post. I'd really like to learn how to porperly work with this system. The legacy system was easy but limited.
     
  3. FileThirteen

    FileThirteen

    Joined:
    Oct 23, 2012
    Posts:
    40
    The issue you are likely running into is the started, performed, and canceled callback methods. They all have specific times that they call the callback methods depending on how you've got the input action asset set up. What is most likely occurring is performed is called once when you press and once when you release. Here is a map of the inputs that I've observed through testing:

    Action Type Button
    Interaction None
    started, performed on button down | canceled on release

    Interaction Press And Release
    started, performed on button down | started, performed again on button up

    Interaction Press Only
    started, performed on button down

    Interaction Release Only
    started on button down | performed on button up

    Interaction Hold
    started on button down | performed once the button is held long enough | canceled when the button is released too early

    Interaction Multi Tap
    started on button down | canceled if button not pressed fast enough soon enough | performed if button pressed enough times fast enough
    note: multitap doesn't work

    Interaction Slow Tap
    started on button down | canceled if you release before min tap duration | performed as soon as you release if the alotted min tap duration has elapsed (happens when you release the button not when the time has elapsed)

    Interaction Tap
    started on button down | performed if you release before the Max Tap Duration | canceled if you hold down past the Max Tap Duration as soon as the duration passes(no event on button up)

    Action Type Value with a button
    Control Type Any, Analog, Axis, Bone, Digital, Double, Dpad, Eyes, Integer, Quaternion, Stick, Touch, Vector2, Vector3
    Interactions None
    started, performed on button down | canceled on button up

    Control Type Vector2 with a joystick
    Interactions None
    started on any joystick movement, performed while joystick is not centered over and over, canceled when release joystick

    ControlType Any, Analog (didn't test the rest but assume it is the same)
    Interactions Press And Release
    started, performed on button down | performed, canceled on button up

    Interactions Press Only
    started, performed on button down | performed, canceled on button up

    Interactions Release Only
    started on button down | performed, canceled on button up

    Interactions Hold
    started on button down | performed after hold time | canceled when stopping game
    note: this seems broken can't get any more actions, it's like it never releases

    Interactions Multi Tap
    started on button down | performed if button is pressed enough times fast enough | canceled if button is not pressed fast enough soon enough
    note: doesn't work it's broken, only get started and canceled no matter what

    Interactions Slow Tap
    started on button down | performed on release if button was held long enough | cancelled on release if button was not held long enough

    Interactions Tap
    started on button down | canceled as soon as Max Tap Duration elapsed | performed if released before Max Tap Duration elapsed

    Action Type Pass Through
    Interactions None
    performed on button down | performed on button up

    Interactions Press and Release
    started, performed on button down | canceled on button up

    Interactions Press Only
    started, performed on button down | canceled on button up

    Interactions Release Only
    started on button down | performed, canceled on button up

    Interactions Hold
    started on button down | performed as soon as hold time elapses | canceled on button up

    Interactions Multi Tap
    started on button down | performed if button pressed enough times fast enough | canceled if button is not pressed enough times fast enough
    note: This seems to be the only multi tap that is actually working

    Interactions Slow Tap
    started on button down | performed on button up if Min Tap Duration elapsed | canceled on button up if Min Tap Duration not elapsed

    Interactions Tap
    started on button down | performed on button up if release before Max Tap Duration | canceled as soon as Max Tap Duration elapsed (no event on button up after Max Tap Duration elapsed)

    So basically you probably have your Interactions set to press and release, just set them to press only and you might be good.

    Also I created a paid asset that wraps the new input system and allows you to essentially write code exactly how you used to in the old Input Manager, you can use Input.GetButtonDown, Input.GetButtonUp, and even Input.GetButton. If you haven't fully converted an old input manager to the new input system it can even make a seamless transition as long as you have your input action asset set up the same way as the input manager settings. Link in my signature.

    It takes the hard part out of the new input system and lets you keep writing your code the way you did before but you get to use the powerful Input Action Assets.
     
  4. Rajivrocks

    Rajivrocks

    Joined:
    Oct 3, 2019
    Posts:
    15
    Thanks a lot, I hope this will help me out in the future.
     
  5. lightbug14

    lightbug14

    Joined:
    Feb 3, 2018
    Posts:
    447