Unity Input System Button Triggers Multiple Times

Viewed 5225

So I've been playing around with the new Input System and things are starting to get a little frustrating. My issue is button pushes are firing multiple times. I've tried multiple settings with the type of action (eg Button, Pass Through etc), and Interactions being set to press only, or release or whatever, doesn't seem to matter. It'll either fire 2 times or 4 times depending on the settings.

I've got multiple controllers here for testing and as if that wasn't confusing enough, if a second or more player joins in, their button pushes trigger only once. It's always only player one's buttons who trigger multiple times. Does anyone know how to fix this?

Looks like I'm not the only one, looking at this forum thread.

Here is my very simple, basic test code just for reference.

public void GetInteractValues( InputAction.CallbackContext value )
 {
     if ( value.started )
         print("foo");
 }
5 Answers

Coming into this late, but in case anyone else is confused: the multiple calls is intended behavior and is listed in the documentation (though the documentation took me a while to find).

Per this comment, check context.performed.

public void OnMyAction(InputAction.CallbackContext context)
{
    if (context.started)
        Debug.Log("Action was started");
    else if (context.performed)
        Debug.Log("Action was performed");
    else if (context.canceled)
        Debug.Log("Action was cancelled");
}

Issue is a bug within Unity. Solution is to check that player prefab is in scene as the player and it's prefab (only on player one) are firing. Use the following to in addition to checking button callback.

gameObject.scene.IsValid()

I don't know if this is in any way helpful, but I was struggling to use the new Input System. Code examples I saw looked overly complicated compared to Input.GetButtonDown(), so I tried using the Player Input Component. I went straight for Behavior == Use Unity Events because it let me link actions to functions/methods in my script. On paper, this sounded good but then my functions were triggering multiple times.

This is just how Unity Events work: "started -> performed -> canceled".

According to the docs, you must set Behavior to SendMessages and set your function/method to public void OnActionName (), e.g. action: Jump, Method: OnJump().
I did this, but it still triggered multiple times. So in the InputAction you need to set the Interaction to Press, but bear in mind Lt and Rt are variable (i.e. push a little to shoot a little, push harder to shoot . . . harder IDK) so untick the Default next to Press Point and set that to 1.

Wish someone had explained this to me 4 days ago. Hope it helps someone.

As LexGear responded here https://stackoverflow.com/a/63459803/5277266, checking if the gameObject is in valid scene is one solution, another one is to check if the gameObject is active :

public void Move(InputAction.CallbackContext ctx)
{
    // to avoid prefab dispatching the event...
    if (!gameObject.activeInHierarchy) // or if (!gameObject.scene.IsValid())
    {
        return;
    }

    // do things with the event
}

In my case, i did that check in the awake method to avoid doing it on each input event. I can do that only because i register C# event to dispatch the input event to multiple objects :

void Awake()
{
    // to avoid prefab dispatching the event...
    if (!gameObject.activeInHierarchy)
    {
        return;
    }

    OnMove += playerController.Move;
}

I had the same issue; the started event handler was called twice - or the performed handler was called twice with context.performed == true.

Problem was that my object got destroyed and recreated but did only register the handler in Awake() but not unregister in OnDestroy(). So the handler was registered twice.

Related