Search Unity

[SOLVED] GetButtonDown / GetButtonUp with the new system

Discussion in 'Input System' started by blitzjoans, Apr 25, 2020.

  1. blitzjoans

    blitzjoans

    Joined:
    Feb 27, 2017
    Posts:
    6
    EDIT: Solution :D https://forum.unity.com/threads/getbuttondown-getbuttonup-with-the-new-system.876451/#post-5764510

    Hello. First of all, congrats for the UI with this new Input System. It's waaaaay better than the old one. The setup of different button for PC/XBOX/PS4 works perfectly!

    However, the new system is also really confusing and i feel that even with all its limitations, the old system was way easier to setup and control.

    I have a simple Jump action that requires GetButtonDown and GetButtonUp. Cool, with the old system it was two lines of code.

    I tried to do this with the new system for hours and i cannot understand how it really works. It doesn't help that the tutorials/videos/forums explain things in 2/3 different ways, and the Migrating section of the documentation is really vague in terms of explaining how to setup ButtonUp/Down.


    So, i ask for help because i feel totally lost:

    This was my previous code
    Code (CSharp):
    1.  public bool GetJump(bool Down)
    2.     {
    3.             if (Down)
    4.             {
    5.                 return Input.GetButtonDown("Jump");
    6.             }
    7.             else
    8.             {
    9.                 return Input.GetButtonUp("Jump");
    10.             }
    11.     }
    And yes, i have read dozens of threads before creating this post. And no, none of the 'solutions' worked. We just want a simple way to get the two events, because this is the nonsense that i have and still fails:


    Code (CSharp):
    1.  private void Awake()
    2.     {
    3.         controls = new PlayerControls();
    4.         controls.Gameplay.Move.performed += ctx => _directionInfo = ctx.ReadValue<Vector2>();
    5.         controls.Gameplay.Jump.started += ctx => _JumpPressed = true; _JumpReleased = false;
    6.         controls.Gameplay.Jump.canceled += ctx => _JumpPressed = false;
    7. }
    My Jump button is set to Tap. It's the closest thing to the previous version of my Jump, but still fails.

    In fact, the closest one was this:
    Code (CSharp):
    1. controls.Gameplay.Jump.performed -= ctx =>
    2.         {
    3.             var control = ctx.control;
    4.             var button = control as ButtonControl;
    5.  
    6.             if (button != null)
    7.             {
    8.                 if (button.wasPressedThisFrame)
    9.                 {
    10.                     _JumpPressed = true;
    11.                     _JumpReleased = false;
    12.                 }
    13.                 else if (button.wasReleasedThisFrame)
    14.                 {
    15.                     _JumpPressed = false;
    16.                     _JumpReleased = true;
    17.                 }
    18.             }
    19.         };
    Jump button on Press and Release. ALMOST WORKS, but i can hold Jump and i will jump constantly once i touch the ground again. With the old system, ButtonDown will be called one time, and i need to ButtonUp for the next Jump.

    Even if i can get this to work, the new system in its current state is way difficult to setup compared to the old one. There are 2/3 ways that i saw on the forums to configure things. It's modularity is killing the most basic setups for a lot of teams, which will end up using the old one or just purchasing one from the Asset Store.
     
    Last edited: Apr 25, 2020
  2. Fenrisul

    Fenrisul

    Joined:
    Jan 2, 2010
    Posts:
    618
  3. blitzjoans

    blitzjoans

    Joined:
    Feb 27, 2017
    Posts:
    6
    Thanks for the help! Sadly, I can't recreate GetButtonDown

    My function sends the actual value of GetButtonDown. So, with the old system, GetButtonDown will be active for a moment.

    Code (CSharp):
    1. return Input.GetButtonDown("Jump");
    However, with the new system and some of the info from your videos,
    Code (CSharp):
    1. bool _JumpPressed;
    2. bool _JumpReleased;
    3.  
    4. (...)
    5.  
    6. controls.Gameplay.Jump.performed += ctx =>
    7.         {
    8.             if (ctx.ReadValueAsButton())
    9.             {
    10.                 _JumpPressed = true;
    11.                 _JumpReleased = false;
    12.             }
    13.             else if (!ctx.ReadValueAsButton())
    14.             {
    15.                 _JumpPressed = false;
    16.                 _JumpReleased = true;
    17.             }
    18.         };
    19.  
    20. (...)
    21.  
    22. public bool GetJump(bool Down)
    23.     {
    24.             if (Down)
    25.             {
    26.                 return _JumpPressed;
    27.             }
    28.             else
    29.             {
    30.                 return _JumpReleased;
    31.             }
    32.     }
    _JumpPressed will be true unless i release the Jump button, which is exactly what happens with the old Input.GetButton, but it isn't what i need (GetButtonDown)

    This code is located on my GameManager, so that's why i have GetJump(); In my PlayerMovement code i have:
    Code (CSharp):
    1. desiredJump = GameManager.GetJump(down);
    2. jumpReleased = GameManager.GetJump;
    So i end up with desiredJump always true.
     
  4. jiraphatK

    jiraphatK

    Joined:
    Sep 29, 2018
    Posts:
    300
  5. blitzjoans

    blitzjoans

    Joined:
    Feb 27, 2017
    Posts:
    6
  6. Fenrisul

    Fenrisul

    Joined:
    Jan 2, 2010
    Posts:
    618
    I need to make a new video! :D Comin up heh.

    But the gist of it is this...

    Code (csharp):
    1.  
    2. public static class InputActionButtonExtensions
    3. {
    4.     public static bool GetButton(this InputAction action) => action.ReadValue<float>() > 0;
    5.     public static bool GetButtonDown(this InputAction action) => action.triggered && action.ReadValue<float>() > 0;
    6.     public static bool GetButtonUp(this InputAction action) => action.triggered && action.ReadValue<float>() == 0;
    7. }
    If you use this method, make sure that your Input System settings match. IE: If you want to use these in FixedUpdate, make sure InputSystem is updating in the Fixed Update loop.

    Also make sure you have the Press Interaction set to "Press and Release" when using this method
     
    kairido1, DaoC00, JirunDev and 2 others like this.
  7. jiraphatK

    jiraphatK

    Joined:
    Sep 29, 2018
    Posts:
    300
    hmm, maybe, try seperating the action to jumPress and jumpRelease then only use the respective pressonly and release only
     
  8. blitzjoans

    blitzjoans

    Joined:
    Feb 27, 2017
    Posts:
    6
    THANK YOU!!!!!!!! Seriously, Unity needs to take a look at this. Is exactly like the previous behaviour, and its waaaaay easier than the current how is explained on the documentation.

    Million thanks, you just saved my day.
     
    Fenrisul likes this.
  9. Fenrisul

    Fenrisul

    Joined:
    Jan 2, 2010
    Posts:
    618
    Welcome!

    It's worth noting that there are some edge cases with this in regards to using things like Gamepad Triggers as "Buttons". Those extension methods don't take the "Press Point" into account at all (ie: does a half-trigger pull resulting in 0.5f mean pressed?) But for the majority of button cases they'll get the job done :)

    @Rene-Damm :)
     
  10. leegod

    leegod

    Joined:
    May 5, 2010
    Posts:
    2,476
    new input system is too F***ed up everyone. who made it? fire him please?
     
    TV4Fun, Arizotel and zeropointblack like this.
  11. Fenrisul

    Fenrisul

    Joined:
    Jan 2, 2010
    Posts:
    618
    It takes a minute to read up on! It is definitely an improvement over the OG input system in 99% of cases. Now that Unity Remote is mostly working there aren't many big killer issues anymore. Your forum acct is as old as mine - can I help you with anything in particular? (I'm on Unity discord as @AngryArugula )
     
  12. zeropointblack

    zeropointblack

    Joined:
    Jun 8, 2020
    Posts:
    197
    I agree with this person ^ ^ ^ ^
     
    Arizotel likes this.
  13. leegod

    leegod

    Joined:
    May 5, 2010
    Posts:
    2,476
    so how to use above extension?

    copy paste above code to somewhere in my script, then what?

    if I want to receive gamepad (nintendo switch pro)'s many buttons, like x, y, a, b, r, l, zr, zl, then how?

    Gamepad.current.buttonEast.GetButtonDown? but buttonEast. then next, there is no GetButtonDown function.
     
  14. jmattarock_unity

    jmattarock_unity

    Joined:
    Mar 10, 2018
    Posts:
    25
    If anyone is still having issues I found an easier solution.

    Code (CSharp):
    1.         private void DoCrouch(InputAction.CallbackContext _obj)
    2.         {
    3.            if(_obj.performed)
    4.            {
    5.              crouch = !crouch;
    6.            }
    7.         }
    this will toggle the button true or false each press.