1
\$\begingroup\$

I'm a very new Unity developer who's looking for a best practice or framework for handling different input modes. I'm working in C#. Here's a contrived example:

Sample Map Application

Control Scheme 1:

  • W/A/S/D keys move map up/right/down/left.
  • Escape key closes application

Spacebar opens menu and switches to Control Scheme 2

Control Scheme 2:

  • W/A/S/D moves menu selection up/down/into submenu/back to parent menu.
  • Escape key closes menu and switches to Control Scheme 1

I realize this is a silly contrived example, but it demonstrates the point. When we are in a menu we don't want the W/A/S/D keys to also move the map while we are trying to navigate the menu. This could be done with a bunch of if statements such as

if(moveMode)
   // read keypresses and move map
else if(menuMode)
   // read keypresses and menu navigation

But you can see how this would get messy very quickly if we had lots of modes. We could also end up with a lot of nested if statements if we have sub-modes for controls.

Surely there's a cleaner way to do this? Any best practices for this? Any frameworks?

\$\endgroup\$

3 Answers 3

1
\$\begingroup\$

The new input system makes this very easy.

Just create an input actions asset with a different action map for each input mode.

If you prefer to work with the auto-generated mapping classes for each input asset, then you can just enable and disable those input actions separately. This can look like this (assuming your input action assets is named "My Input Actions" and you enabled "Generate C# Class" on it):

private void Awake() {
    myInputActions = new myInputActions();

    myInputActions.Scheme1.SwitchToScheme2.performed += ((InputAction.CallbackContext ctx) => {
         myInputActions.Scheme1.enabled = false;
         myInputActions.Scheme2.enabled = true;             
    }
    // other event handlers for myInputActions.Scheme1

    myInputActions.Scheme2.SwitchToScheme1.performed += ((InputAction.CallbackContext ctx) => {
         myInputActions.Scheme1.enabled = true;
         myInputActions.Scheme2.enabled = false;             
    }
    // other event handlers for myInputActions.Scheme2

    myInputActions.Enable();
}

When you prefer to use the Player Input component, you can use the method SwitchCurrentActionMap:

private void OnSwitchToScheme1() {
    GetComponent<PlayerInput>().SwitchCurrentActionMap("Scheme1");
}

private void OnSwitchToScheme2() {
    GetComponent<PlayerInput>().SwitchCurrentActionMap("Scheme2");
}
\$\endgroup\$
0
\$\begingroup\$

Event handlers.

When your map is open or gains focus, it subscribes to key events.

InputManager.OnKeyPressed += HandleKeyPress;

When your map closes or loses focus, it unsubscribes from key events.

InputManager.OnKeyPressed -= HandleKeyPress;

Here's a Unity example and video about it.

\$\endgroup\$
2
  • \$\begingroup\$ My use case actually uses joystick values as well. So I don't know if an event-driven system is sufficient. \$\endgroup\$
    – J-bob
    Commented Apr 30, 2018 at 20:24
  • 1
    \$\begingroup\$ It is. It's the same strategy. Joystick changes can be event driven as well. \$\endgroup\$
    – House
    Commented Apr 30, 2018 at 22:22
-1
\$\begingroup\$

You could just use the Unity Input System. It is designed to handle contextual mappings, remappings, and support for multiple input methods.

https://docs.unity3d.com/Packages/[email protected]/manual/QuickStartGuide.html

\$\endgroup\$
2
  • 1
    \$\begingroup\$ I agree that the new input system was designed with scenarios like this in mind and makes it much easier to handle them. But the article you linked to does not address this specifically. Instead of just linking to the frontpage of the documentation, could you perhaps explain in your own words how to switch between different control schemes using the new input system? That would make this a much better answer. \$\endgroup\$
    – Philipp
    Commented Mar 28, 2021 at 9:20
  • \$\begingroup\$ @Philipp No, I could not. I am terrible about explaining systems I from day 0 have considered self-explanatory at a glance. \$\endgroup\$
    – Weckar E.
    Commented Mar 28, 2021 at 11:49

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .