unity-game-enginegame-development

Using Unity New Input System To Create Custom Interaction - Issue Detecting Button Hold Threshold Reached


So I created a custom interaction for the Unity New Input System, which allows me to hold a button and charge an attack, and then release the button when the threshold has been reached to launch the charged attack. However, I am unable to actually send a message or detect when the hold threshold has been reached.

I want to be able to use that information to either update the UI, or something. Could use help figuring out what's wrong with this implementation.

using UnityEngine.InputSystem;
using UnityEditor;
using UnityEngine;
using System.Collections;
using Unity.VisualScripting;


#if UNITY_EDITOR
[InitializeOnLoad]
#endif
public class HoldAndReleaseInteraction : IInputInteraction
{
    //Above this value a tap is pressed
    public float pressPoint = 0.5f;
    public float holdTime = 1.0f; // Time required to hold before release is valid

    float buttonPressCounter;
    private float pressTime;
    private bool isHolding = false;

    static HoldAndReleaseInteraction()
    {
        InputSystem.RegisterInteraction<HoldAndReleaseInteraction>();
    }

    public void Process(ref InputInteractionContext context)
    {
      

        if (context.ControlIsActuated(pressPoint)) // Button is pressed
        {
           

            if (!isHolding)
            {
                isHolding = true;
                pressTime = Time.time;
                context.Started(); // Register that the hold has started
             

            }
            if (Time.time - pressTime >= holdTime)
            {
          

                //context.Performed(); // Action triggers on release
            }

        }
        else if (isHolding) // Button is released
        {
            if (Time.time - pressTime >= holdTime)
            {
            
           
               context.Performed(); // Action triggers on release
            }
            else
            {
                context.Canceled(); // Release was too early
             
            }
            Reset(); // Reset state for next interaction
        }

   
    }

    public void Reset()
    {
        isHolding = false;
      
    }


}

Solution

  • So I figured out how to solve this. Posting it here incase someone has this issue and comes across the question

    I basically just created a static function inside of another class that takes in the hold time and the isHolding bool, and from there I run a coroutine that uses the holdTime for a wait time, and thus I can trigger the message.

    1. Add Static Function for HoldAttackCheck inside of another class (in this case, SpecialAttackSystem
    public static void HoldAttackCheck(bool isHolding, float holdTime)
      {
          holdingAttack = isHolding;
          holdingTimeParam = holdTime;
          instance.StopCoroutine("HoldCheckCoRoutine");
          instance.StartCoroutine("HoldCheckCoRoutine");
      }
    
    1. Add calls to this function inside of my HoldAndReleaseInteraction
        public void Process(ref InputInteractionContext context)
        {
    
    
            if (context.ControlIsActuated(pressPoint)) // Button is pressed
            {
    
              
    
                if (!isHolding)
                {
    
                    isHolding = true;
                    SpecialAttackSystem.HoldAttackCheck(isHolding, holdTime);
                    pressTime = Time.time;
                    context.Started(); // Register that the hold has started
                }
        
    
            }
            else if (isHolding) // Button is released
            {
                if (Time.time - pressTime >= holdTime)
                {
    
                
                    context.Performed(); // Action triggers on release
                }
                else
                {
                    SpecialAttackSystem.HoldAttackCheck(!isHolding, holdTime);
                    context.Canceled(); // Release was too early
    
                }
                Reset(); // Reset state for next interaction
            }
    
    
        }
    
        public void Reset()
        {
            isHolding = false;
            **SpecialAttackSystem.HoldAttackCheck(isHolding, holdTime);**
        }
    
    
    1. Add a coroutine to check the values and display a message when complete or canceled
       {
        
               yield return new WaitForSeconds(holdingTimeParam);
    
               if (holdingAttack)
               {
                   Debug.Log("Charged Attack!");
               }
               else if (!holdingAttack)
               {
                   Debug.Log("Not Charging!");
               }
    
       }