Search Unity

Button held logic. I feel like i'm missing something

Discussion in 'Input System' started by fatality674, Aug 4, 2019.

  1. fatality674

    fatality674

    Joined:
    Nov 1, 2012
    Posts:
    24
    I am just playing around with the new input system and I am trying to grasp how it handles button holding.


    I have set up the button like so...



    How do I go about triggering different logic between when the button is held vs pressed?


    As an example, a standard attack from a character, vs a charged up attack when held...

    Below is what I have so far but I feel like I'm missing something with the new input system.

    Code (CSharp):
    1.     private ControllerMap _controlMap;
    2.  
    3.     private IEnumerator ButtonHeld;
    4.    
    5.     void Awake()
    6.     {
    7.         _controlMap = new ControllerMap();
    8.         _controlMap.CharacterControl.SetCallbacks(this);
    9.     }
    10.  
    11.     void OnEnable()
    12.     {
    13.         _controlMap.CharacterControl.South.Enable();
    14.     }
    15.  
    16.     void OnDisable()
    17.     {
    18.         _controlMap.CharacterControl.South.Disable();
    19.     }
    20.  
    21.     public void OnSouth(InputAction.CallbackContext context)
    22.     {
    23.  
    24.         if (context.started)
    25.         {
    26.             if (ButtonHeld != null)
    27.             {
    28.                 StopCoroutine(ButtonHeld);
    29.             }
    30.             ButtonHeld = SouthHeld();
    31.             StartCoroutine(ButtonHeld);
    32.         }
    33.  
    34.         if (context.canceled)
    35.         {
    36.            
    37.             if (ButtonHeld != null)
    38.             {
    39.                 StopCoroutine(ButtonHeld);
    40.             }
    41.             if (context.time - context.startTime < 0.3)
    42.             {
    43.                 Debug.Log("X pressed logic");
    44.             }
    45.             else
    46.             {
    47.                 Debug.Log("X no longer held");
    48.             }
    49.          
    50.         }
    51.  
    52.     }
    53.     private IEnumerator SouthHeld()
    54.     {
    55.         yield return new WaitForSeconds(0.3f);
    56.         Debug.Log("X held logic");
    57.     }
     
  2. TRS6123

    TRS6123

    Joined:
    May 16, 2015
    Posts:
    246
    I'd use two separate input actions: one for the button being pressed and the other for the button being held. That way you can keep the pressed and held logic separate from each other.
     
    fatality674 likes this.
  3. fatality674

    fatality674

    Joined:
    Nov 1, 2012
    Posts:
    24
    Oh i see! I was treating actions like potential buttons/axis being used and not using it like potential actions. Thanks for that!
     
  4. Rene-Damm

    Rene-Damm

    Joined:
    Sep 15, 2012
    Posts:
    1,779
    Just to add that, it is possible to have this sitting on the same binding. Interactions can be stacked, though not every combination makes sense. The system goes through the interactions top down and interactions higher up the stack get to drive an action before interactions lower down the stack do.

    Anyway, here is an example of a fire action where the button can be tapped for immediate firing or held for charged firing. This is adapted from SimpleDemo.

    Code (CSharp):
    1. // Note the two interactions. "tap" will require a press-and-release within tap time.
    2. // If the button is held for longer, the action automatically transitions into a "slowTap".
    3. var fireAction = new InputAction(name: "fire",
    4.     binding: "<Gamepad>/buttonSouth",
    5.     interactions: "tap;slowTap");
    6.  
    7. fireAction.performed +=
    8.     ctx =>
    9. {
    10.     if (ctx.interaction is SlowTapInteraction)
    11.     {
    12.         StartCoroutine(BurstFire((int)(ctx.duration * burstSpeed)));
    13.     }
    14.     else
    15.     {
    16.         Fire();
    17.     }
    18.     m_Charging = false;
    19. };
    20. fireAction.started +=
    21.     ctx =>
    22. {
    23.     if (ctx.interaction is SlowTapInteraction)
    24.         m_Charging = true;
    25. };
    26. fireAction.canceled +=
    27.     ctx =>
    28. {
    29.     m_Charging = false;
    30. };