Hello,
I was wondering if this was expected behaviour.
Say I have the following code (see below), where m_reference1 and m_reference2 are both buttons, and are bound to the same keyboard input (in this case, the ‘B’ button).
My expected flow would be :
m_reference1is enabled- User presses ‘B’ button
m_reference1is triggeredm_reference1is disabledm_reference2is enabled- the end.
But what actually happens is :
m_reference1is enabled- User presses ‘B’ button
m_reference1is triggeredm_reference1is disabledm_reference2is enabledm_reference2is triggered…
It seems that if one action enables another, and if they both have the same binding, the second action will automatically get triggered with the same input. Seems like a bug to me, right ?
It is causing some issues for me where I have a UI Map with ‘B’ to close a menu, which returns to my player’s action map which has ‘B’ to perform another action. It ultimately means that when I press ‘B’ both actions happen at once, which is definitely not what I want.
To me, any actions that are enabled after a button action has been registered should be ignored.
Is this something in my setup I can fix? or is this just a limitation of the Input system?
using System;
using UnityEngine;
using UnityEngine.InputSystem;
public class InputTest : MonoBehaviour
{
[SerializeField]
private PlayerInput m_playerInput;
[SerializeField]
private InputActionReference m_reference1;
[SerializeField]
private InputActionReference m_reference2;
private void Awake()
{
m_playerInput.onActionTriggered += EVENT_OnTriggered;
m_playerInput.actions.FindActionMap("TestMap").Enable();
EnableAction(m_reference1);
}
private static void Log(string a_prefix, string a_text)
{
Debug.Log($"[{Time.frameCount}: {a_prefix}] {a_text}");
}
private void EnableAction(InputActionReference a_ref)
{
Log("EnableAction", a_ref.name);
var action1 = m_playerInput.actions.FindAction(a_ref.action.id);
action1.Enable();
}
private void DisableAction(InputActionReference a_ref)
{
Log("DisableAction", a_ref.name);
var action1 = m_playerInput.actions.FindAction(a_ref.action.id);
action1.Disable();
}
private void OnDestroy()
{
m_playerInput.onActionTriggered -= EVENT_OnTriggered;
}
private void EVENT_OnTriggered(InputAction.CallbackContext a_obj)
{
if (a_obj.action.id != m_reference1.action.id &&
a_obj.action.id != m_reference2.action.id)
return;
Log("EVENT_OnTriggered", $"{a_obj.action.name}: {a_obj.phase}");
if (a_obj.phase != InputActionPhase.Performed)
return;
if (a_obj.action.id == m_reference1.action.id)
{
DisableAction(m_reference1);
EnableAction(m_reference2);
}
}
}
For those curious, the exact output from the Log is:
[0: EnableAction] TestMap/Action1
[307: EVENT_OnTriggered] Action1: Started
[307: EVENT_OnTriggered] Action1: Performed
[307: DisableAction] TestMap/Action1
[307: EVENT_OnTriggered] Action1: Canceled
[307: EnableAction] TestMap/Action2
[307: EVENT_OnTriggered] Action2: Started
[307: EVENT_OnTriggered] Action2: Performed
[315: EVENT_OnTriggered] Action2: Canceled
