Problem when switching between two action maps

Hello, fellow users!

I’m trying to switch between two different Action Maps - Player and Inventory - depending on whether the inventory is on or off. However, for some reason my movement doesn’t work when I switch back from the Inventory Action Map to the Player Action Map.

And the funny thing is: any other action from the Player Action Map works, but not the movement one. I’m not doing anything complex for the movement logic (just a simple movement using Rigidbody 2D) and debugged everything movement-related, but no success. And the WASD keys are indeed being read from the Input Debug window. :thinking:

I’m using an Unity Event to call the PlayerInput Component .SwitchCurrentActionMap() method to switch between Player and Inventory Action Maps.

My Inputs are set like this:

Player


Inventory

As for my scripts, I separated my input logic from my controller logic (and to simplify, I just added a Debug.Log to my HandleMovement() method for testing purposes), so I have basically the following:

using UnityEngine;

public class PlayerMovementController : MonoBehaviour
{
    [SerializeField] private Rigidbody2D rigidbody;
    
    private Vector2 movementDirection;

    private void FixedUpdate() => HandleMovement();
    
    public void MoveTo(Vector2 direction) => movementDirection = direction;

    private void HandleMovement()
    {
        if (movementDirection.x != 0f) Debug.Log("Move!");
    }
}
using Sirenix.OdinInspector;
using UnityEngine;
using UnityEngine.InputSystem;

public class MovementInputReader : MonoBehaviour
{
    [Title("Movement Properties")]
    [SerializeField] private PlayerMovementController playerMovementController;
    
    private InputAction movementAction;

    private void OnEnable()
    {
        movementAction = InputSystem.actions["Move"];
        
        movementAction.performed += OnMove;
        movementAction.canceled += OnMove;
    }

    private void OnDisable()
    {
        movementAction.performed -= OnMove;
        movementAction.canceled -= OnMove;
    }
    
    private void OnMove(InputAction.CallbackContext inputContext)
    {
        var movementDirection = inputContext.ReadValue<Vector2>();
        
        playerMovementController.MoveTo(movementDirection);
    }
}
using Sirenix.OdinInspector;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.InputSystem;

public class InventoryInputReader : MonoBehaviour
{
    [Title("Inventory Properties")]
    [SerializeField] private PlayerInventoryController playerInventoryController;
    [SerializeField] private UnityEvent OnShowInventory;
    [SerializeField] private UnityEvent OnHideInventory;

    private InputAction playerInventoryAction;
    private InputAction inventoryAction;
    
    private void OnEnable()
    {
        playerInventoryAction = InputSystem.actions["ToggleInventory"];
        inventoryAction = InputSystem.actions.FindActionMap("Inventory").FindAction("Toggle");
        
        inventoryAction.Disable();
        
        playerInventoryAction.performed += OnToggle;
        inventoryAction.performed += OnToggle;
    }

    private void OnDisable()
    {
        playerInventoryAction.performed -= OnToggle;
        inventoryAction.performed -= OnToggle;
    }
    
    private void OnToggle(InputAction.CallbackContext inputContext)
    {
        if (playerInventoryAction.enabled)
        {
            OnShowInventory?.Invoke();
            inventoryAction.Enable();
            playerInventoryAction.Disable();
        }
        else
        {
            OnHideInventory?.Invoke();
            inventoryAction.Disable();
            playerInventoryAction.Enable();
        }
        
        playerInventoryController.Toggle();
    }
}

I’m using Input System 1.11.1 (and using the new static class InputSystem instead of a reference to the PlayerInput Component) and Unity 2022.3.50f.

Am I doing something wrong (perhaps using something incorrectly)? Has anyone come across this situation? :thinking:

Are you referencing InputSystem.actions in your playerInput code ?
PlayerInput makes a copy of the input action asset so you should reference its asset. See
https://docs.unity3d.com/Packages/com.unity.inputsystem@1.11/api/UnityEngine.InputSystem.PlayerInput.html#UnityEngine_InputSystem_PlayerInput_actions
and some notes here:
https://docs.unity3d.com/Packages/com.unity.inputsystem@1.11/manual/PlayerInput.html#ui-input

You could try disconnecting your input action asset from the project wide input actions and removing the usage of InputSystem.actions to see if the project wide input actions are part of your issue here.

By referecing it, you mean through a GetComponent or serialize field? If that’s what you’re saying, not quite. Both my PlayerInput as well as the Project-wide Actions in the Project Settings are referencing the same asset file.

Btw, I got it working by disabling “Enable Input Consumption” in the settings and I don’t know why it worked. I don’t even know if that’s the right thing to do.
I don’t have that scenario in my game, but what if I needed it to be enabled so I could use inputs like “Press Key X + Space Bar” to do something? AFAIK, if I have an action mapped to Space Bar and another to Key X, a third action using a modifier with those 2 keys wouldn’t work properly since the input system would either execute action mapped to Space Bar or Key X. That’s what “Enable Input Consumption” solves, right?

Any thoughts?

Its not obvious to me why disabling “Enable Input Consumption” would fix your issue.
It might help if you add another screenshot here with the Keyboard and Gamepad bindings expanded to show what they map to.

You could raise a bug and attach your project if you believe this is unexpected.

Enable Input Consumption is documented here:
https://docs.unity3d.com/Packages/com.unity.inputsystem@1.11/manual/ActionBindings.html#multiple-input-sequences-such-as-keyboard-shortcuts

In your example with
action1 - X + SPACE
action2 - X
action3 - SPACE

Without “Enable Input Consumption”
1, 2 and 3 would fire for X + SPACE
2 would fire for just X
3 would fire for just SPACE

You could remove action1 and handle this manually with just action2/action3 and managing the combined state in user code.

With “Enable Input Consumption”
1 would fire for X + SPACE (2 and 3 would be lower complexity and would be ignored)
2 would fire for just X
3 would fire for just SPACE