Search Unity

New Input System: Multiple Action Maps

Discussion in 'Input System' started by Deleted User, Jan 20, 2019.

  1. Deleted User

    Deleted User

    Guest

    They don't work. Only the first one does. An attempt to use an action from the second+ map leads to:
    Code (CSharp):
    1. IndexOutOfRangeException: Index was outside the bounds of the array.
    2. UnityEngine.Experimental.Input.InputActionMapState.ChangePhaseOfAction (UnityEngine.Experimental.Input.InputActionPhase newPhase, UnityEngine.Experimental.Input.InputActionMapState+TriggerState& trigger, UnityEngine.Experimental.Input.InputActionPhase phaseAfterPerformedOrCancelled) (at Library/PackageCache/com.unity.inputsystem@0.1.2-preview/InputSystem/Actions/InputActionMapState.cs:845)
    3. UnityEngine.Experimental.Input.InputActionMapState.ChangePhaseOfInteraction (UnityEngine.Experimental.Input.InputActionPhase newPhase, UnityEngine.Experimental.Input.InputActionMapState+TriggerState& trigger, System.Boolean remainStartedAfterPerformed) (at Library/PackageCache/com.unity.inputsystem@0.1.2-preview/InputSystem/Actions/InputActionMapState.cs:752)
    4. UnityEngine.Experimental.Input.InputInteractionContext.Started () (at Library/PackageCache/com.unity.inputsystem@0.1.2-preview/InputSystem/Actions/InputInteractionContext.cs:90)
    5. UnityEngine.Experimental.Input.Interactions.PressAndReleaseInteraction.Process (UnityEngine.Experimental.Input.InputInteractionContext& context) (at Library/PackageCache/com.unity.inputsystem@0.1.2-preview/InputSystem/Actions/Interactions/PressAndReleaseInteraction.cs:32)
    6. UnityEngine.Experimental.Input.InputActionMapState.ProcessInteractions (System.Int32 mapIndex, System.Int32 controlIndex, System.Int32 bindingIndex, System.Double time, System.Int32 interactionStartIndex, System.Int32 interactionCount) (at Library/PackageCache/com.unity.inputsystem@0.1.2-preview/InputSystem/Actions/InputActionMapState.cs:624)
    7. UnityEngine.Experimental.Input.InputActionMapState.ProcessControlStateChange (System.Int32 mapIndex, System.Int32 controlIndex, System.Int32 bindingIndex, System.Double time, UnityEngine.Experimental.Input.LowLevel.InputEventPtr eventPtr) (at Library/PackageCache/com.unity.inputsystem@0.1.2-preview/InputSystem/Actions/InputActionMapState.cs:546)
    8. UnityEngine.Experimental.Input.InputActionMapState.UnityEngine.Experimental.Input.LowLevel.IInputStateChangeMonitor.NotifyControlStateChanged (UnityEngine.Experimental.Input.InputControl control, System.Double time, UnityEngine.Experimental.Input.LowLevel.InputEventPtr eventPtr, System.Int64 mapControlAndBindingIndex) (at Library/PackageCache/com.unity.inputsystem@0.1.2-preview/InputSystem/Actions/InputActionMapState.cs:455)
    9. UnityEngine.Experimental.Input.InputManager.FireStateChangeNotifications (System.Int32 deviceIndex, System.Double internalTime, UnityEngine.Experimental.Input.LowLevel.InputEvent* eventPtr) (at Library/PackageCache/com.unity.inputsystem@0.1.2-preview/InputSystem/InputManager.cs:2963)
    10. UnityEngine.Experimental.Input.InputManager.OnUpdate (UnityEngine.Experimental.Input.InputUpdateType updateType, UnityEngine.Experimental.Input.LowLevel.InputEventBuffer& eventBuffer) (at Library/PackageCache/com.unity.inputsystem@0.1.2-preview/InputSystem/InputManager.cs:2693)
    11. UnityEngine.Experimental.Input.LowLevel.NativeInputRuntime+<>c__DisplayClass6_0.<set_onUpdate>b__0 (UnityEngineInternal.Input.NativeInputUpdateType updateType, System.Int32 eventCount, System.IntPtr eventPtr) (at Library/PackageCache/com.unity.inputsystem@0.1.2-preview/InputSystem/NativeInputRuntime.cs:110)
    12. UnityEngineInternal.Input.NativeInputSystem.NotifyUpdate (UnityEngineInternal.Input.NativeInputUpdateType updateType, System.Int32 eventCount, System.IntPtr eventData) (at C:/buildslave/unity/build/Modules/Input/Private/Input.cs:91)
    I have tried recreating the .inputactions and .inputsettings, checked in a different project.
     
  2. Rene-Damm

    Rene-Damm

    Joined:
    Sep 15, 2012
    Posts:
    1,779
    Yup, several users have run into the same issue. There's a fix in the pipeline. Will be included in the next package.
     
    GilbertoBitt likes this.
  3. chris73it

    chris73it

    Joined:
    Oct 15, 2013
    Posts:
    21
    Any updates? I did not know about this issue and yesterday I tried to define a second ActionMap and failed: any ETA available?
     
  4. ModLunar

    ModLunar

    Joined:
    Oct 16, 2016
    Posts:
    374
    @Rene-Damm Also came across this issue, but no errors in my case.

    I have 1 InputActionAsset that contains 2 ActionMaps, and the second ActionMap is being completely ignored it seems, while the first one works fine.
    I'm using the PlayerInput components that should work fairly easily out of the box :) hopefully this is an easy fix or I'm doing something silly!

    EDIT: Nevermind, my "SendMessage"s were not being called cause my Actions were named with spaces in them! I was able to successfully use 1 InputActionAsset with 2 ActionMaps, and had 2 PlayerInput components (each referencing 1 of the ActionMaps) -- it all works great in Unity 2020.1.0a18 and InputSystem preview.3 - 1.0.0.
     
    Last edited: Jan 21, 2020
    tigerleapgorge likes this.
  5. transat

    transat

    Joined:
    May 5, 2018
    Posts:
    779
    Sh
    Why 2 PlayerInput components? Isn’t this what SwicthCurrentActionMap is for? I’m asking because I’m about to experiment with map switching.
     
  6. ModLunar

    ModLunar

    Joined:
    Oct 16, 2016
    Posts:
    374
    I have a player with 1 PlayerInput component, and then the camera which uses different controls, with a 2nd PlayerInput component.

    Is there a better way I should use in that case? (I'm also very new to this system)
     
  7. transat

    transat

    Joined:
    May 5, 2018
    Posts:
    779
    If you’re using the one controller for both camera and character then I think you should have only one PlayerInput component. In the case of a game pad you can set your left stick to move the character and your right stick (or mouse) to do your camera stuff.
     
  8. ModLunar

    ModLunar

    Joined:
    Oct 16, 2016
    Posts:
    374
    Gotcha, so where should that 1 PlayerInput component go, on the camera or the player's hierarchy?
     
  9. transat

    transat

    Joined:
    May 5, 2018
    Posts:
    779
    On your player if you want it to send messages or on any game object if you want to broadcast messages or use Unity events, AFAIK. I use it to send Unity events so keep it separate to my character so that I can still have it active if I switch characters. So basically I have one player game object and one character game object (the one with your character controller on it). And if you use PlayerInputManager then you don’t need your character prefab in the scene when it starts. One character can be instantiated for every different interface the system picks up. Check out the input system demos available through the Package Manager.
     
    ModLunar likes this.
  10. ModLunar

    ModLunar

    Joined:
    Oct 16, 2016
    Posts:
    374
    Okay, so I am limited for time, and see these demos available, but I don't think any of them address my issue (please correct me if I'm wrong, but I really don't have the time at my job to look into all of these).

    upload_2020-2-14_10-39-48.png

    I have a 1 player game, but wish to keep the controls modular so I can easily activate/deactivate logic parts of the input. @Rene-Damm It would really help me to be able to use 2 or more PlayerInput components, so one can handle the movement (stuff that changes your position/rotation), and another can handle the cursor-related stuff (changing from showing the cursor to hidden, etc).

    It seems that when I have 2 PlayerInputs, they auto-assign to player ids 0 and 1 (not sure if that's relevant), and the 1st PlayerInput's SendMessages stop working only partially. Some of the actions' messages still go through, while other messages do not go through.

    I was hoping to also do this because when you go Create > Input Actions, I thought it'd be nice to separate the 2 into 2 separate assets, one for the movement controls, and the other asset for the cursor controls.

    Is this a bug, or am I doing this wrong? I'd like to emphasize I want to keep it modular, so 1 PlayerInput component wouldn't be great.

    ---

    I also know that 1 InputActions asset can have multiple maps. But to my understanding, only 1 of these is activated at a time, right?
     
  11. ModLunar

    ModLunar

    Joined:
    Oct 16, 2016
    Posts:
    374
    For now, it seems I can use 2 PlayerInput components that both use the same InputActionAsset:

    upload_2020-2-14_10-57-31.png

    But hopefully I can separate the Actions out into 2 or more InputActionAssets someday or something like that :)
     
  12. transat

    transat

    Joined:
    May 5, 2018
    Posts:
    779
    @ModLunar shouldn’t you be using 2 action maps (one for the movement, one for the UI) and switch between the two instead of 2 player inputs?
     
    TP3 likes this.
  13. transat

    transat

    Joined:
    May 5, 2018
    Posts:
    779
    Because what you’re describing is exactly what the system is designed to do. Action maps allow you to map the actions to different sets (maps).
     
    TP3 likes this.
  14. ModLunar

    ModLunar

    Joined:
    Oct 16, 2016
    Posts:
    374
    @transat Thanks :) but unfortunately for our case we need both active at the same time. Is that possible with the Action maps?
     
    TP3 likes this.
  15. transat

    transat

    Joined:
    May 5, 2018
    Posts:
    779
    @ModLunar There are different things you could do that would probably achieve your aims but it’s hard to suggest solutions if I don’t know the exact problem. What are you trying to achieve by having 2 simultaneous sets? An actionmap maps 1 input to 1 action though that action can send an event (via PlayerInput) that takes into account game or input parameters to call different functions.
     
  16. ModLunar

    ModLunar

    Joined:
    Oct 16, 2016
    Posts:
    374
    I know it's abstract, but I believe the specifics are irrelevant. We need to be able to...

    1. Turn ON and OFF certain "groups" of input controls.
    2. Have MULTIPLE of those "groups" ON at the same time.


    Is there a way to achieve this?


    I feel like it should be simple, but from my understanding, in 1 InputActionAsset, you can only activate 1 ActionMap at a time, right? (This is a problem with (2) from above).
     
  17. transat

    transat

    Joined:
    May 5, 2018
    Posts:
    779
    1. You can switch action maps through code or by setting a control/input in your action map to send an unity event to “switchCurrentActionMap” in PlayerInput. This essentially turns on/off certain groups of controls, your stated aim. So when I press the Menu button on my game pad it switches to the UI action map and my jump button is now select, for example.

    2. Why not just combine the 2 action maps into one if there’s no crossover in controls used? And if there is crossover, why not set PlayerInput or some other file to sort that out? Hard to suggest a solution without knowing what you’re trying to achieve by #2.
     
    Last edited: Feb 16, 2020
  18. ModLunar

    ModLunar

    Joined:
    Oct 16, 2016
    Posts:
    374
    I see.. hmm.. I guess I'll have to accept only 1 ActionMap being on at a time then. Thanks for the help @transat :)
     
  19. Rene-Damm

    Rene-Damm

    Joined:
    Sep 15, 2012
    Posts:
    1,779
    This is facilitated by "binding groups" (i.e. InputBinding.groups). Any binding can belong to arbitrary many groups and arbitrary sets of groups can be enabled at any one time.

    Unfortunately, support for setting this up through the UI isn't really there ATM. The only thing in the UI that sets up binding groups ATM is control schemes (which get mapped to binding groups) and the control scheme handling that PlayerInput/InputUser has is currently locked to having only a single active control scheme.

    You could still set up a number of control schemes and then manually activate several in code. Or set it all up in code.

    Code (CSharp):
    1. // Create an asset with one map and one action.
    2. var asset = ScriptableObject.CreateInstance<InputActionAsset>();
    3. var map = new InputActionMap("map");
    4. asset.AddActionMap(map);
    5. var action = map.AddAction("action");
    6.  
    7. // Add a binding that is active in group A and B.
    8. action.AddBinding("somepath", groups: "A;B");
    9.  
    10. // Add a binding that is active only in group C.
    11. action.AddBinding("somepath", groups: "C");
    12.  
    13. // Enable groups B and C. Can switch this arbitrary many times.
    14. asset.bindingMask = new InputBinding { groups = "B;C" };
    15.  
    PlayerInput will only enable one at a time by itself but you can just bypass PlayerInput here and enable and disable things arbitrarily.

    Code (CSharp):
    1. // Enable Actions1 and Actions2 action map.
    2. playerInput.actions.FindActionMap("Actions1").Enable();
    3. playerInput.actions.FindActionMap("Actions2").Enable();
     
    Jiaquarium and rboerdijk like this.
  20. MikeGDev

    MikeGDev

    Joined:
    Dec 19, 2017
    Posts:
    53
    I was using the InputActionAsset to enable/disable the maps that were needed at a given time. However, now I needed to listen for onActionTriggered from the PlayerInput and notiched that there doesnt seem to be a connection between the asset and the PlayerInput in terms of which action maps are active. In order to make the same set of actions trigger through PlayerInput I have to manually activate the maps on the PlayerInput even though the input is already enabled/disabled in the game.
    I find this a bit confusing. If the action maps are disabled on the asset and input is not received in the game, how can is still be received on the PlayerInput? Is it correct to use the two solutions together?
     
  21. adehm

    adehm

    Joined:
    May 3, 2017
    Posts:
    369
    Problem with
    Code (CSharp):
    1. var asset = ScriptableObject.CreateInstance<InputActionAsset>();
    or
    Code (CSharp):
    1. InputActionAsset asset = new InputActionAsset();
    They stay in memory in the editor and every time the project is ran that session the memory keeps building up until an error occurs for exceeding the limit of a byte; only being cleared by closing the project.