How do we switch action maps? I can't wrap my head around all of these things

Hi,

Let’s say I have these action maps

  1. Player (has WASD controls)
  2. Camera (has WASD controls)
  3. Photo Controller (has WASD controls)
  4. Ui

Now let’s say we enable the Player action map and the player can move - great, then we switch to photo controller action map by

        playerInput.SwitchCurrentActionMap("photo controller:);

and now we can move the photo controller, but the player also moves?? Why? Why switching my action map does not disable the old one? On top of that we can enable actions individually by

             InputActionReference _myAction // SerializedField and assigned in the inspector
            _myAction.action.performed += OnAnyKeyPressed;
            _myAction.action.Enable();

Okay what happens if _myAction is a part of UI action map and I enable it whilst the Player action map is active and then switch to Camera action map? I guess everything is going to work which is weird because I swapped the action map, but on the other side if everything except UI stops working, then if I switch out of my UI state to Player how am I supposed to enable _myAction once again if it was a part of some script’s Awake method? Everything is so confusing we can enable disable switch swap change toggle flip and at the end we got keybinds from 50 different action maps and the player ends up receiving WASD inputs from action maps that are meant to work for cameras or other things.

What do I mean by that, simple case:

        _playerInput.actions["ESC"].performed += OnActionPerformed;

vs

        var escapeAction = _playerInput.currentActionMap.FindAction("ESC");
        escapeAction.performed += OnActionPerformed;

vs

       [SerializeField] private List<InputActionReference> _inputActions;
       foreach (var inputAction in _inputActions)
        {
         inputAction.action.performed += OnActionPerformed;
        }

Which one should we use? Why there are so many ways to do the same thing?

Is there someone who used that system for something other than a 10 minute youtube tutorial and can come and say NEVER use that approach and use that instead!?

What happens when you enable an individual InputAction is described in the docs: Class InputAction | Input System | 1.0.2

Namely it will enable the corresponding map, but only that action will be enabled.

When it comes to swapping between different control systems its up to you disable and enable them in a way that works for your project, as this is generally project specific stuff. You will need to introduce the appropriate systems to deal with this, such as exposing methods to enable/disable maps in various components. Lots of ways to set it up.

I don’t think you switch you disable one when you don’t need it and enable it when you do right?

I would just handle the enable and disable manually as multiple action maps can be active at the same time.

1 Like

I have been using this a lot and now I think its the wrong way because I got to manually disable them when I switch the ActionMap

       [SerializeField] private List<InputActionReference> _inputActions;

OnEnable...
       foreach (var inputAction in _inputActions)
        {
         inputAction.action.performed += OnActionPerformed;
        }

That is assigning a function to a specific input. This is enabling the action map, meaning every input is enabled.

_myAction.action.actionMap.Enable();

Enables the ENTIRE action map. You can then do _myAction.action.actionMap.Disable(); to disable the action map.

So lets say you push a button to enter a car, you enable the car action map and maybe disable the normal walking around one, then when you exit the car you disable the car action map and enable the normal one. While simultaneously you might keep a camera control action map untouched for both since they use the same thing.

1 Like

I did this and thought it Disables and Enables the new one, but seems like it does not

        playerInput.SwitchCurrentActionMap(newActionMap.ToString());

_playerInput is your generated C# file yes? That will be separate to the actual input action assets.

You can probably also just CRTL-Click on the method in your code editor and it will take you to the source code so you can see what it actually does.

Yeah I saw it does this

    public void SwitchCurrentActionMap(string mapNameOrId)
    {
        // Must be enabled.
        if (!m_Enabled)
        {
            Debug.LogError($"Cannot switch to actions '{mapNameOrId}'; input is not enabled", this);
            return;
        }

        // Must have actions.
        if (m_Actions == null)
        {
            Debug.LogError($"Cannot switch to actions '{mapNameOrId}'; no actions set on PlayerInput", this);
            return;
        }

        // Must have map.
        var actionMap = m_Actions.FindActionMap(mapNameOrId);
        if (actionMap == null)
        {
            Debug.LogError($"Cannot find action map '{mapNameOrId}' in actions '{m_Actions}'", this);
            return;
        }

        currentActionMap = actionMap;
    }

Just do it manually, you don’t need this function and it may not do what you think. Maybe just setup a state machine to manage this or something.

1 Like