Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Tap, Hold, Double Tap on one Button

Discussion in 'Input System' started by coffeelisk, Nov 21, 2021.

  1. coffeelisk

    coffeelisk

    Joined:
    Feb 19, 2021
    Posts:
    5
    I am currently trying to give a Button 3 interaction.
    OnRelease
    OnHold
    OnMultiTap
    Code
    Code (CSharp):
    1. private void OnEnable()
    2. {
    3.        input.Player.AttackOnRelease.performed += AttackOnRelease;
    4.        input.Player.AttackOnHold.performed += AttackOnHold;
    5.        input.Player.AttackOnDoubleTap.performed += AttackOnDoubleTap;
    6.        input.Player.AttackOnRelease.Enable();
    7.        input.Player.AttackOnHold.Enable();
    8.        input.Player.AttackOnDoubleTap.Enable();
    9.        input.Player.Dash.Enable();
    10.     }
    Code (CSharp):
    1.     private void AttackOnRelease(InputAction.CallbackContext context)
    2.     {
    3.         Debug.Log("AttackOnRelease"+context);
    4.         shoot.AttackOnRelease();
    5.     }
    6.     private void AttackOnHold(InputAction.CallbackContext context)
    7.     {
    8.         Debug.Log("AttackOnHold"+context);
    9.         shoot.AttackOnHold();
    10.     }
    11.     private void AttackOnDoubleTap(InputAction.CallbackContext context)
    12.     {
    13.         Debug.Log("AttackOnDoubleTap"+context);
    14.         shoot.AttackOnDoubleTap();
    15.     }


    AttackOnrelease: Interactions: Press: Trigger Behaviour: Release Only
    AttackOnHold: Interactions: Hold:
    AttackOnDoubleTap: Interactions: Multitap: Tap Count 2

    AttackOnrelease works fine and always triggers when the button is released, which is a Problem.
    AttackOnHold works fine but I would like it to also trigger on release.
    AttackOnDoubleTap works sometimes and othertimes not.

    What I want.
    AttackOnHold: should be executed once I release the button.
    AttackOnDoubleTap: should only be called when double tapping.
    AttackOnrelease: should be called on release.

    What I don't want is for them to be all called together at the same time.

    Feel free to ask if something is unclear.
    Thanks.
     
  2. BillyWM

    BillyWM

    Joined:
    Dec 29, 2018
    Posts:
    14
    The Input System doesn't support preemption so you'll need to read up on the phases and then code your own logic so that when one of those reaches performed it preempts the other.


    https://docs.unity3d.com/Packages/com.unity.inputsystem@1.0/manual/KnownLimitations.html
    Phases explanation: https://docs.unity3d.com/Packages/c...1.0/manual/Actions.html#responding-to-actions

    I did implement something like this where you can press, hold, or double-tap for different results and that's how I went about it (i.e. phase checking and some manual bookkeeping). Also make sure set the Action Type type to Pass Through.

    You can look at .started, .cancelled, .performed on the context. You have your callbacks set up to only fire on performed but in my case I did more of the configuration through the editor and just checked "if (context.performed) ..... etc ...." . You'll need to fire them in other phases for this.

    Having Hold preempt Press is easy enough. I gave the Press an Interaction with Trigger Behavior of "release only" and then when context.performed is observed for Hold it preempts the Press (I manually check this). I have various Hold actions that need to preempt presses so I ended up with a dictionary of active preemptions.

    Adding in Double Tap was trickier but basically....

    * Press just notes for later (manually) that there's an action to perform
    * Hold clears out what Press stored and does the hold action instead, preempting others
    * Double Tap preempts both of these
    * If Double Tap reaches *cancelled* then it finally does the stored Press action

    Depending on the timeframes you have configured it *is* possible for a user to perform and Hold and a Double Tap so take care that all preempt the others.

    I used three Actions with three associated callbacks but you can do it in one by checking context.Interaction
     
    coffeelisk likes this.