As the title says, if you change between Action maps on the fly via code, the next button press just simply won’t register. However, if you create an Action in the new ActionMap you are changing to on the same binding, it will trigger.
Recreation:
Create 2 ActionMaps: ActionMap1, ActionMap2.
Create a button press Action for ActionMap1 and bind it on keyboard Q.
Create a button press Action for ActionMap2 and bind it on keyboard E.
Create a gameobject and add the PlayerInput script, set the Actions to the one you just created.
Set the default map to ActionMap1.
Set the behaviour to SendMessages.
Create a script which changes to ActionMap2 when pressing Q on ActionMap1, and changes to ActionMap1 when pressing E.
After pressing Q, you have to press E twice, then press Q twice to make them trigger.
I have uploaded a Test.rar which has a SampleScene in the Scenes folder. Start it, then start pressing Q and E to change between maps.
I tried your sample and modified the code to add an actions.Enabled() method call as follows:
public void OnActionMap1Action()
{
Debug.Log($"OnActionMap1Action invoked. {_playerInput.currentActionMap.name} to MAP2");
_playerInput.SwitchCurrentActionMap("ActionMap2");
_playerInput.actions.Enable();
}
public void OnActionMap2Action()
{
Debug.Log($"OnActionMap2Action invoked. {_playerInput.currentActionMap.name} TO MAP1");
_playerInput.SwitchCurrentActionMap("ActionMap1");
_playerInput.actions.Enable();
}
This seems to give the correct behaviour. Which, is better than I’m getting at the moment with some code that switches Action Maps and after the switch I get no input at all from the second map!
Looking at this again it’s perhaps not what you want to call_player.actions.Enable(); as that will enable all action maps and you (we) want to swap action maps on some code trigger. So this modification does that. It also works for my action switching code as well!
public class InputManager : MonoBehaviour
{
[SerializeField] private PlayerInput _playerInput;
public void OnActionMap1Action()
{
Debug.Log($"OnActionMap1Action invoked. {_playerInput.currentActionMap.name} to MAP2");
//_playerInput.SwitchCurrentActionMap("ActionMap2");
//_playerInput.actions.Enable();
_playerInput.currentActionMap.Disable();
_playerInput.SwitchCurrentActionMap("ActionMap2");
_playerInput.currentActionMap.Enable();
}
public void OnActionMap2Action()
{
Debug.Log($"OnActionMap2Action invoked. {_playerInput.currentActionMap.name} TO MAP1");
//_playerInput.SwitchCurrentActionMap("ActionMap1");
//_playerInput.actions.Enable();
_playerInput.currentActionMap.Disable();
_playerInput.SwitchCurrentActionMap("ActionMap1");
_playerInput.currentActionMap.Enable();
}
}
In may case the problem was that I had an action called “Jump” in both action maps and although they were bound to different gamepad buttons that seems to have banjaxed the input system. Smells like a bug to me - you should be able to have two input maps which have some action names in common.
My answer was way too short and not very understandable, sorry for that. I mean that your workaround can work if you have only one Action map active at a time. (SwitchCurrentActionMap(“”).
If you use actionMap1.enable/actionMap2.disable, you still have the unwanted behavior: 2 times button/key pressing is needed to trigger.
Then I switched the Interaction on that Action to “Release Only” and it started working.
Seems the preliminary analysis of others in this thread is correctly : if you call SwitchCurrentActionMap() during the Completed-phase of a “Press Only” Interaction, the control-state becomes unstable.