Why do Actions in disabled ActionMaps still trigger Performed events?

What I’m trying to achieve is to enable only the corresponding ActionMap based on the state of the game, and disable all other ActionMaps, what is the right way to do it?

According to the documentation and the discussion I googled, PlayerInput can only have one enabled ActionMap at a time.
To my understanding, only Actions in the enabled ActionMap can trigger Performed events in response to user input.
If that’s not the case, then I’m totally confused.

Here is the actual situation I encountered:




[RequireComponent(typeof(PlayerInput))]
public class InputLogger : MonoBehaviour
{
    private PlayerInput _pInput;
    public PlayerInput PInput => _pInput ??= gameObject.GetComponent();

    void Start()
    {
        // both Jump and Sumbit are binding with buttonSouth[Gamepad]/ Enter[Keyboard]
        PInput.actions.FindAction("Test").performed += c => { Debug.Log("Test"); };
        PInput.actions.FindAction("Submit").performed += c => { Debug.Log("Submit"); };

        foreach (var map in PInput.actions.actionMaps)
        {
            Debug.Log($"{map.name} {map.enabled}");
        }

        PInput.SwitchCurrentActionMap("UI");
        PInput.SwitchCurrentActionMap("Player");

        foreach (var map in PInput.actions.actionMaps)
        {
            Debug.Log($"{map.name} {map.enabled}");
        }
    }
}

Click Play

20240930-141247

  1. The DefaultActionMap of PlayerInput is “Player”, but the log shows that both “Player” and “UI” are enabled at the beginning.
    (I remember in a previous discussion, someone encountered the same problem, and the reason was related to PlayerInput referencing EventSystem, but in my case there is no EventSystem.)

  2. On Start(), the ActionMap “UI” is already disabled, but Action “Submit” is still able to trigger Performed.

PS. I’ve tried the recommended Action workflow, but our game needs to support local multiplayer, and according to the docs, I should use PlayerInput.

The issue is resolved, and I hope this can help others who encounter the same problem.

Solution: When you are using only one PlayerInput component, set the Project-wide Actions to None.

image

The documentation does not mention this detail, and following the instructions in the documentation can actually lead to issues.

The documentation states:


I’m so confused…

I used the PlayerInput component and listened only to its Actions, so why is it still being affected by the Project-wide Actions?

It seems that they are both referencing the same instance of Actions, and they are both working at the same time.

So, does the statement in the documentation, “When multiple Player Input components use the same Actions, the components automatically create private copies of the Actions,” mean that if there is only one PlayerInput component referencing the same Input Actions asset as the Project-wide Actions, the PlayerInput will not create its own copy?

If that’s the case, then why can an Action within an ActionMap that I have disabled through the PlayerInput component still trigger a Performed event?