Immerseum SDK: VR Simulator (version: BETA-0.9)
      [view as: Desktop | Tablet | Mobile]
Custom InputAction Mapping
In This Topic

While the VRSimulator has defined a rather comprehensive set of default Input Actions for you, there may be situations where you wish to either:

Using C# scripting and the InputActionInputAxis, and InputButton classes (and their derivatives) you can do all three of the items above.

Be Careful! Be Careful!

We consider Custom InputAction Mapping to be the most complicated type of integration with the VRSimulator.

Because it directly relates to the inputs that will be captured from your users, mistakes, bugs, inefficiencies, etc. made here are likely to fundamentally destabilize your user experience.

Proceed at your own risk.

Input System Overview

The way movement works in any VR experience (or computer game, etc.) is really straightforward:

 

The software needs to receive (capture) the user's input from whatever device was used. Based on the input received (what button was pressed, what thumbstick was moved, etc.) the system needs to decide what that input means ("Move the player forward", "Fire the blaster cannon", etc.). And once that decision is made, the system needs to respond and do whatever it should do ("Move the player one step forward", "Start the process of firing the blaster cannon").

Where this can get complicated is that most input devices are built and designed differently, have different hardware features, different drivers, etc. And different experiences (and even different users within the same experience!) may want to have different button layouts, controller configurations, etc. for their style of play. Trying to accommodate all of the variability that's out there can get very complicated, very fast.

Which is why we have broken this process into four key concepts:

 

How InputActions Work

The InputActionManager Explained

Input Actions are coordinated by the InputActionManager ConfigurationScripting ]. The InputActionManager is a singleton class which exposes the majority of its functionality via static methods. Its responsibilties are simple:

While the InputActionManager exposes a variety of static properties and methods that you can read from, you will most likely be using:

Anatomy of an InputAction

An InputAction represents a collection of inputs that correspond to the same intent. For example:

While it is possible for an InputAction to correspond to one and only one input device's button/axis, the key benefit of using InputActions is to simplify code by applying the same logic to all inputs that mean the same thing.

InputActions only expose two public methods: InputAction.registerAction() and InputAction.deregisterAction(). As the method names suggest, these methods register and deregister the InputAction with the InputActionManager.

The key component of the InputAction, however, are its properties. These properties can be divided into three categories:

The list below describes those properties which are most important for defining custom InputActions:

Best Practice Best Practice

Many InputActions will feature both keyboard, button, or axis inputs. For example, one potential InputAction would be to "move forward" based either on the keyboard's W key, the gamepad's right thumbstick, or the mouse's scroll wheel.

To properly define such an InputAction, these would need to be included in the appropriate properties described above.

Be Aware Be Aware

Technically, there is nothing stopping you from including a particular input (a UnityEngine.KeyCode, an InputAxis, or an InputButton) in multiple InputActions.

This might lead to some strange behavior (because one input will actually be tied to multiple intentions), but there are certain situations where that may be desired behavior.

For example, it would be perfectly reasonable to include the same input in three InputActions where one InputAction will only apply in the "normal" state, a different one will apply if your user has paused the game, and a third might apply if the user is in a "swimming" state.

Anatomy of an InputAxis

An InputAxis is used to define a single input which returns a quantitative value of its state (as opposed to a boolean, like a keyboard input). In a non-VR game, such input axes get defined in the Unity Input Manager and you can just access them using Unity's brilliant Input API.

However, one of the challenges in developing for VR is that the Unity Input Manager does not support VR-compatible input devices like the HTC/Vive Wands and Oculus Touch. They can only be accessed through the SteamVR and Oculus Utilities for Unity plugins respectively.

To address this challenge, the VRSimulator input system supports three types of InputAxis (all derive from the generic InputAxis):

Each InputAxis has a set of read-only properties which return the results (the value) of the axis at any given moment. They are fairly clearly documented.

However, when creating a custom InputAction it is important to understand the definition fields that need to be configured:

An OculusInputAxis receives certain additional definition properties:

SteamVRInputAxis also receives certain additional definition properties:

Anatomy of an Input Button

An InputButton is used to define a single input which returns a button state (pressed, released, held, etc.). In a non-VR game, such buttons get defined in the Unity Input Manager and you can just access them using Unity's brilliant Input API.

However, one of the challenges in developing for VR is that the Unity Input Manager does not support VR-compatible input devices like the HTC/Vive Wands and Oculus Touch. They can only be accessed through the SteamVR and Oculus Utilities for Unity plugins respectively.

To address this challenge, the VRSimulator input system supports multiple types of InputButton (all derive from the generic InputButton):

Each InputButton has a set of read-only properties which return the results (the value) of the button at any given moment. They are fairly clearly documented.

However, when creating a custom InputAction it is important to understand the definition fields that need to be configured:

MouseButton receives certain additional definition properties:

All OculusButtons (including OculusTouchButton and OculusNearTouchButton) receives certain additional definition properties:

All SteamVRButtons (including SteamVRHairTrigger and SteamVRTouch) also receives certain additional definition properties:

Modifying Registered InputActions

The best way to modify default InputActions is to do so when the EventManager.OnInitializeInputActionsEnd event fires. At that point, all InputActions have been registered with the InputActionManager and can safely be modified without fear of being over-written by the VRSimulator's initialization logic.

There are a variety of ways to programmatically modify registered InputActions, but the way that we recommend is to:

  1. Retrieve the InputAction from the InputActionManager.
  2. Make appropriate modifications to the InputAction.
  3. Deregister the modified InputAction from the InputActionManager.
  4. Register the modified InputAction from the InputActionManager.
Be Aware Be Aware
The workflow described above will not work properly if you modify the InputAction's name property (this is used to uniquely identify the InputAction, after all).

The following is an example of this workflow in action. This example adds pressing the Spacebar to the "togglePauseMenu" default InputAction:

using UnityEngine;
using Immerseum.VRSimulator;

public class myClass : MonoBehaviour {
   void OnEnable() {
      EventManager.OnInitializeInputActionsEnd += modifyInputAction;
   }

   void OnDisable() {
      EventManager.OnInitializeInputActionsEnd -= modifyInputAction;
   }

   void modifyInputAction() {
      InputAction actionToModify = InputActionManager.getInputAction("togglePauseMenu");
      actionToModify.pressedKeyList.Add(KeyCode.Space);
      actionToModify.deregisterAction();
      actionToModify.registerAction();
   }
}

Extending Default InputActions

Adding a new InputAction to the VRSimualtor's movement systregisterAction Methodem is relatively simple:

  1. Create an InputAction with an appropriate and unique name (i.e. a name that doesn't already exist among registered InputActions).
  2. Call the InputAction.registerAction() method on it.

Below is an example that does this to create a new "PressTheKButton" InputAction:

using UnityEngine;
using Immerseum.VRSimulator;

public class myClass : MonoBehaviour {
   void Start() {
      InputAction myInputAction = new InputAction();
      myInputAction.name = "pressTheKButton";
      myInputAction.pressedKeyList.Add(KeyCode.K);
      myInputAction.registerAction();
   }
}

Replacing Default Input Actions

If you intend to replace all of the default InputActions with your own, you don't have to go through the modification workflow described above for each one. It is easier to:

  1. Turn off Use Immerseum Defaults in the InputActionManager's settings.
  2. Define your own custom InputActions with the same names as our default InputActions.
  3. At runtime, register your custom InputActions with the InputActionManager. This can most easily occur when EventManager.OnInitializeInputActions fires.

The example below provides some sample code for doing so:

using UnityEngine;
using Immerseum.VRSimulator;

public class myClass : MonoBehaviour {
   void OnEnable() {
      EventManager.OnInitializeInputActions += createCustomInputActions;
   }

   void OnDisable() {
      EventManager.OnInitializeInputActions -= createCustomInputActions;
   }

   void createCustomInputActions() {
      InputAction firstInputAction = new InputAction();
      firstInputAction.name = "togglePauseMenu";
      firstInptuAction.pressedKeyList.Add(Keycode.Space);
      firstInputAction.registerAction();

      // Repeat for additional Input Actions
   }
}

Provided you left the Default Input Map setting enabled in the MovementManager's settings, you will now simply have different buttons activating the same movement logic.

Replacing Default Input Actions and Movement Logic

Putting all of the above together with Custom Input Handling, it is possible to both replace all of the default Input Actions and apply your own custom movement logic. Simply:

  1. Turn off Default Input Maps in the MovementManager settings.
  2. Follow the steps for Replacing Default Input Actions described above.
  3. Either create custom listeners for each of your custom InputActions, or create a switchboard listener for all of them.
See Also

Scripting Reference

 

 


2016 Copyright © Immerseum Inc. All rights reserved.

Send Feedback