Search Unity

Press and release button

Discussion in 'Input System' started by Zelop, Mar 3, 2019.

  1. Zelop

    Zelop

    Joined:
    Jul 28, 2016
    Posts:
    8
    Hi,
    I try to make a 2D game using the new input system. But i have a problem : I don't know how to recognize if I'm pressing or releasing a button.
    I want to make my jump like that :
    - when I press space, I jump
    - when I release space, I stop the jump
    But I don't know how to know if i'm pressing or releasing in the event i call.
    Can someone give me a solution ?
    Thank you.
     
  2. SpookyCat

    SpookyCat

    Joined:
    Jan 25, 2010
    Posts:
    3,760
    Input.GetKeyDown and Input.GetKeyUp
     
    franpo697 likes this.
  3. Zelop

    Zelop

    Joined:
    Jul 28, 2016
    Posts:
    8
    Yes I used that before to know the new Input System, but now i'm not sure this is the right option. Because i'm not using Input.getKeyDown (or up) but event with action map
     
  4. Innovine

    Innovine

    Joined:
    Aug 6, 2017
    Posts:
    522
    I am also curious as to how this works in the new Input system.
    I can get my OnButton callback triggered on both key down and key up, but calling context.ReadValue<bool>() results in a bunch of exceptions. I cant see anything else in the context which would indicate that this is a key down or a key up. Am I supposed to set something special in the Action bindings?
     
  5. recursive

    recursive

    Joined:
    Jul 12, 2012
    Posts:
    669
    If you look at the Action binding, there should be a "Continuous" flag. With that you can get started phase for down, Performed Phase for held, and Cancel Phase for released.

    EDIT: For a button action, there's also the PressAndRelease flag on the Press Interaction.
     
  6. Innovine

    Innovine

    Joined:
    Aug 6, 2017
    Posts:
    522
    Didn't work quite like that for me. So I went and checked these variables and setting exhaustively, and finally found a combination that works:

    Set Continuous to false. Set Interactions to Press.
    This gives you one callback on key down, and one on key up, and you can tell which is which by the value of context.performed.

    Using continuous doesn't allow you to see which msg is the unique key down, but cancelled was true only once on key up.


    I feel that this is unnecessarily complicated and not at all intuitive. Maybe Unity could clean it up a bit?
     
    MassimoFrancesco likes this.
  7. Nixaan

    Nixaan

    Joined:
    May 30, 2013
    Posts:
    118
    I don't mess with Continuous and Interactions at all. The interactions/continuous situation is like - InputSystem: "You want advanced functionality?", Me: "Yes, sure.", InputSystem: "Great... but that will cost you basic functionality!". Depending on Continuous/Interaction combo, Started and Canceled events may or may not be called at all and Performed may be at the beginning, or at the end, or for the whole duration.

    IMO Started, Performed, Canceled should be events that are 100% guaranteed/stable functionality. And there should be pollable version of them (in specific situations polling an input is all you need instead of constantly subbing/unsubbing for events, or enabling/disabling).

    BTW next is what I use for polling InputAction/ButtonControl. Haven't tested it enough but it seems to work so far.

    Code (CSharp):
    1.  
    2.         public bool GetButtonDown(InputAction inputAction)
    3.         // public bool GetButton(InputAction inputAction)
    4.         // public bool GetButtonUp(InputAction inputAction)
    5.         {
    6.             if (inputAction.lastTriggerControl is ButtonControl bc)
    7.             {
    8.                 return bc.wasPressedThisFrame;
    9.                 // return bc.isPressed;
    10.                 // return bc.wasReleasedThisFrame;
    11.             }
    12.             return false; // warning?
    13.         }
     
    adsilcott likes this.
  8. WilliamBenichou

    WilliamBenichou

    Joined:
    Apr 11, 2016
    Posts:
    9
    Hi guys, I faced this problem no later than yesterday and I think i'm using a much shorter and cleaner solution. Without any modifier on the InputAction, I just let it to the type "Button". Then you just have to register on the "started" and on the "cancelled" events.
    Hope that helps anybody that pass by.

    Code (CSharp):
    1. GameInput myActions = new GameInput();
    2. myActions.Main.Shoot.started += _ => {Debug.Log("Started pressing space");};
    3. myActions.Main.Shoot.canceled += _ => {Debug.Log("Released space");};
     
    rednoux, LordOlives and Noble-Woods like this.
  9. Ramsestone

    Ramsestone

    Joined:
    Oct 22, 2020
    Posts:
    2
    I've managed to solve this by using the returning value of the action Jump to check when is pressed and when is released. While it's pressed it returns 1, if it's not then it returns 0.

    Code (CSharp):
    1.  
    2. //Call this function on FixedUpdate()
    3.  
    4. void modifyPhysics()
    5. {
    6.         // Set returning value of the action Jump to a variable
    7.         float jumpState = (controls.Player.Jump.ReadValue<float>());
    8.  
    9.             if (jumpState == 0 && !isGrounded)
    10.             {
    11.                 rb.gravityScale = gravity * (fallMultiplier / 2);
    12.             }
    13. }
     
  10. Rene-Damm

    Rene-Damm

    Joined:
    Sep 15, 2012
    Posts:
    1,779
    Note that as of 1.1-preview.2, there were some extensions to the InputAction API to work with buttons more easily. (CHANGELOG, docs).

    Code (CSharp):
    1. // GetButton("fire")
    2. playerInput.actions["fire"].IsPressed()
    3.  
    4. // GetButtonDown("fire")
    5. playerInput.actions["fire"].WasPressedThisFrame()
    6.  
    7. // GetButtonUp("fire")
    8. playerInput.actions["fire"].WasReleasedThisFrame()
     
  11. Ramsestone

    Ramsestone

    Joined:
    Oct 22, 2020
    Posts:
    2
    That's awsome! Thank you so much!
     
  12. sany101

    sany101

    Joined:
    May 28, 2017
    Posts:
    4


    Version 1.1-preview.2 is not available in the package Manager, at least on Unity 2019.4.13f1.

    I was looking for a solution to the same problem and had to invent a Bicycle to solve it. At the moment, "new input system" is not convenient for development.
     
  13. Rene-Damm

    Rene-Damm

    Joined:
    Sep 15, 2012
    Posts:
    1,779
    Make sure to enable "Show preview packages".

    upload_2020-11-2_12-39-15.png
     
  14. jarbleswestlington_unity

    jarbleswestlington_unity

    Joined:
    Dec 6, 2017
    Posts:
    32

    Please tell me there's a more direct event for a key being released now and this isn't still the "official" solution to this problem?
     
  15. Last edited by a moderator: Jul 30, 2021
  16. cLick1338

    cLick1338

    Joined:
    Feb 23, 2017
    Posts:
    74
    That doesn't help much since it's not using InputAction. At that point might as well use the old system.

    I'm curious about what the best practice is too (using Actions). I tried polling .triggered in Update() (directly replacing the old GetKey/GetButton) but it works completely inconsistently in my project.

    And side note as I'm typing 1.0.2 is the latest release version and (in my 2021.1.15f project enabling pre-release packages doesn't make them show up no matter the amount of refreshes or restarts).
     
    Last edited: Jul 30, 2021
  17. cLick1338

    cLick1338

    Joined:
    Feb 23, 2017
    Posts:
    74
    For now I've settled on doing something like:
    Code (CSharp):
    1. _jumpInput.performed += _ => OnJump(true);
    2. _jumpInput.canceled += _ => OnJump(false);
    _jumpInput is an InputAction. Seems to work as intended so far. Still curious about the proper way to do it with polling.
     
  18. You said
    You haven't mentioned any actions...

    What does this even mean? What do you mean "it works completely inconsistently"?
    You really shouldn't poll, but if you want, .triggered is the right way.

    Because of this you only can install unreleased versions this way.

    This isn't quite polling though and this is a proper way of handling things.