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

Having MultiTap Interaction Issues

Discussion in 'Input System' started by wingeddemon12, Apr 2, 2020.

  1. wingeddemon12


    Apr 2, 2020

    Creating a fighter game, and one of the controls is dashing, so when you double tap in a direction, (left or right), it will dash accordingly. I am using the MultiTap Interaction, but have ran into a few problems.

    1.) I first tried to put MutliTap onto the movement action, like the picture below. When I did this, my understanding at the time was that interactions were a addition, like an extra check, but instead it basically overwrote my movement. So when I pressed to move left or right, I would move a little and stop, I assume that is because it was only checking if I did Multi tap and that is all, you can see the code below as well.

    Code (CSharp):
    2.         controls.PlayerControls.Dash.started += ctx =>
    3.         {
    4.             Movement(ctx.ReadValue<Vector2>());
    5.         };
    6.         controls.PlayerControls.Dash.performed += ctx =>
    7.         {
    8.             if (ctx.interaction is MultiTapInteraction)
    9.                 Dash(ctx.ReadValue<Vector2>());
    10.             else
    11.                 Movement(ctx.ReadValue<Vector2>());
    12.         };
    13.         controls.PlayerControls.Dash.canceled += ctx =>
    14.         {
    15.             Movement(ctx.ReadValue<Vector2>());
    16.         };
    2.) After that didn't work out, I decided to make a separate action for dash, and put MultiTap on there, like the picture below. The input was working, I could move around, and when I double tapped it would hit the Dash function. But now I couldn't get the ReadValue, which I need it to find which direction the player is dashing, I tried Vector 2 at first, then I tried just a float for the 1D Axis, but neither worked, debug just showed that the values passed as 0. I will also paste the code I used for this method.

    Code (CSharp):
    2.         controls.PlayerControls.Dash.performed += ctx =>
    3.         {
    4.             if (dash_ctx.interaction is MultiTapInteraction)
    5.                 Dash(ReadValue<float>());
    6.         };
    3.) The last method I tried was to have 2 different actions, one for dash left and another for dash right. I just had the bindings as a button type. It seemed to work at first, but the only MutliTap controls that were getting performed was the Joystick; the dpad and WASD keys were not registering tapping twice.

    Thanks for any solution/feedback you can give me.

    Attached Files:

  2. Rene-Damm


    Unity Technologies

    Sep 15, 2012
    It's possible to set this up purely at the binding level but it'll lead to a short initial recognition delay while the system is figuring out whether it's looking at a multi-tap or a normal press.

    MultiTap won't work properly on controls or composites other than buttons. An axis or vector composite will not work properly with the interaction.

    While it is technically possible to put interactions on the part bindings of composites, you won't be able to properly tell the difference between a multi-tap and a normal press which you need for your code to be able to tell the difference the two when the inputs sit on a single action.

    So, what works ATM, is to create four actions, one for each cardinal direction. And then to add a MultiTap *on top* and a Press *below*. What this leads to is MultiTap getting first call on processing input. When the user presses a direction and holds it down for longer than the tap delay time (this is where the initial recognition delay is coming from), the MultiTap cancels and the Press starts instead.


    Code (CSharp):
    1. Vector2 m_MoveDirection;
    2. bool m_Dash;
    4. void OnMoveLeft(InputAction.CallbackContext context)
    5. {
    6.     if (!context.performed)
    7.         return;
    8.     if (context.interaction is MultiTapInteraction)
    9.         m_Dash = true;
    10.     m_MoveDirection.x = -1;
    11. }
    Unfortunately, the stack system for interactions is not very flexible yet so this may prove to be an unsatisfactory setup as the user will have to release a particular direction after a double-tap in order to be able to go into a normal press.
    brandonschlosser101 likes this.
  3. filod


    Oct 3, 2015
    MultiTap also won't work when i use stick as Button (say push stick left on gamepad twice), any advice?

    besides, multi tap also only works in Pass-Through type action, is that a "bug" or a "feature" (someone also proposed here )

    in my experiment, when using Value/Button type action, `context.ControlIsActuated(pressPointOrDefault)` would return false on my second press, really weird though.
  4. FlavioIT


    Apr 20, 2015
    Shouldn't I be able to get the press button event if there isn't a double click?
    I'm trying this on the mouse left button and I'm not able to make it work.
    I mean, dbl click is intercepted, the single one nope. Tried inverting the interactions and I'm getting the single press twice (every time I press the button once) or four time if I go for the double click.
    mrsnipey_unity and ICBusch like this.
  5. djcraemer


    Jan 5, 2021
    Has a better solution for this been figured out yet?

    Is it possible to double-tap the key and on the 2nd tap continue to hold down resulting in a dash, then a continued run?

    I'm having a similar issue where I can configure a multi-tap interaction, but the interaction requires the 2nd button push to keyUp. This results in the need to push the key down a 3rd time to perform a dash, then continue running in the same direction.
    deplorablemountaineer likes this.
  6. wheee09


    May 21, 2018
    This was particularly frustrating - I was trying to do a Hold and Tap interaction with an Axis composite (WS and AD)... and if I have the Tap interaction BEFORE the Hold Interaction (ie. on top) then the Tap event will have the correct -1 or 1 value. But if I have the Hold Interaction on top of the Tap interaction, then Tap events will always have a 0 value.

    Screen Shot 2022-04-22 at 9.10.45 PM.png

    The fact that the list of Interactions is actually ORDERED is not obvious (and one would think it shouldn't be by design)...

    Something needs to be fixed there imo.
  7. Lurking-Ninja


    Jan 20, 2015
    So, the change order buttons are there just for decoration?
  8. wheee09


    May 21, 2018
    Oh! Well color me silly, I clearly didn't see that. I even thought to at one point to try and drag and drop to re-order.

    Also sad that I even clicked the delete buttons numerous times.

    That being said, there's a lot to be improved upon with regards to the UI - which all contributed to me missing that. For instance:
    1. Excessive "Open Input Settings" buttons. One is enough.
    2. The warnings "Uses "Default Button Press Point..." are redundant and can be improved by making them on-hover tooltips instead
    3. The reorder buttons and the delete buttons should be more pronounced. They're small, faint and easy to miss.
    4. The children elements (ie. Tap/Hold) should be drag/drop-able - especially since the Actions table to the left is drag/drop-able.
    Last edited: Apr 23, 2022
  9. vassago1


    Aug 12, 2022
    Hi there!

    First of all, english is not my native language. I'm sorry for my possible misspelling :oops:.

    I'm not sure if I understand the problem here, but I've been trying to deal with multitap and move direction issues with the new InputSystem.
    I needed to implement "Dash" in my 2d sidescroll metroidvania pressing one direction twice. I realized that default multitap interaction in the InputSystem requires to "release" the second tap in order to "perform" de action. That causes 1: lag in the dash action (because of the release timing) and 2: you can't hold the 2nd tap expecting the character to run after dash.

    Looking for the solution, I found that you can define custom interactions usable from the InputSystem tool.

    I've created the following class:

    Code (CSharp):
    1. using UnityEditor;
    2. using UnityEngine;
    3. using UnityEngine.InputSystem;
    5. #if UNITY_EDITOR
    6. [InitializeOnLoad]
    7. #endif
    9. public class DashInteraction : IInputInteraction
    10. {
    11.     public float firstTapTime = 0.2f;
    12.     public float tapDelay = 0.5f;
    14.     [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.BeforeSceneLoad)]
    15.     private static void Initialize() { }
    17.     static DashInteraction() {
    18.         InputSystem.RegisterInteraction<DashInteraction>();
    19.     }
    21.     void IInputInteraction.Process(ref InputInteractionContext context)
    22.     {
    23.         if (context.timerHasExpired) {
    24.             context.Canceled();
    25.             return;
    26.         }
    28.         switch (context.phase)
    29.         {
    30.             case InputActionPhase.Waiting:
    31.                 if (context.ControlIsActuated(firstTapTime))
    32.                 {
    33.                     context.Started();
    34.                     context.SetTimeout(tapDelay);
    35.                 }
    36.                 break;
    38.             case InputActionPhase.Started:
    39.                 if (context.ControlIsActuated())
    40.                     context.Performed();
    41.                 break;
    42.         }
    43.     }
    45.     void IInputInteraction.Reset() { }
    46. }

    Then I've returned to the InputSystem tool and I've defined two new actions (one for each direction in my game, using "Button" Action Type) and I've selected the Dash interaction (our custom one). DashInteraction.png

    I used "Button" Action Type because is enought for my case, but I think that it is possible to apply this solution for axis (Vector) Action Type reading the Unity Manual. Just check it out (last code block):

    Hope it works for you