Jan 12 · 11 min read

SteamVR’s new Input System offers developers the ability to abstract key mechanics or “actions” of a VR Experience/Game and map them to any number of controllers Steam supports.

Unreal Engine 4.21 (UE4.21) introduced support for this new Input System, however the current implementation is neither straight-forward nor complete. As one of the lucky devs to have gotten access to earlier prototypes of the upcoming Knuckles Controllers, for which this Input System has been developed somewhat in lock-step, I’ve put together this compendium to help other UE4 VR developers maximise their use of SteamVR’s new Input System.

It’s important to note there are already plugins which automate all or parts of the steps discussed here in an attempt to provide a stop-gap for full official support. Some examples of these is my Project SunRock along with an effort being put in by a team from Valve with input from Epic Games for a more permanent solution via an official UE4 SteamVR Plugin.

You can read through this article from beginning to end as each chapter flows naturally to the next. Opening with a Quickstart for those who just wants to get up and running quickly, then each concept is explained in detail across the succeeding chapters.

You are of course welcome to jump to chapters that are of particular interest:

Chapter I: Quickstart
Chapter II: Understanding UE4 Input Abstractions
Chapter III: Introducing Steam’s New Input System
Chapter IV: Enabling SteamVR Input Support
Chapter V: What Unreal Does For You (UE 4.21)
Chapter VI: What The Engine Does Not Do For You
Chapter VII: How to Define Your Input-To-Action Mappings Manually
Chapter VIII: Project SunRock

Peer Reviewed by:
Joe Radak
et al (undisclosed)


Activating UE’s support for the SteamVR Input system can be done in three main steps as shown in the following video:

  1. If you’re not using UE4’s Input Abstraction already in your project, set this up FIRST as the Engine would look for the Action and Axis Mappings to generate the necessary SteamVR Input files.
  2. Once you have Action and Axis Mappings setup in your UE4 project, add the following lines in your project’s DefaultEngine.ini file:


3. Setup Controller Input Profile Bindings in the SteamVR Input Dashboard.


You can enable the Input binding interface at SteamVR > Settings > Developer

This provides you a Developer Output for your Controller Input Profile…

… and a live input debugger


Before delving to SteamVR’s Input System, let’s review Unreal’s built-in Input Abstraction.

For those who have used this Engine feature before, you’re aware Engine level inputs are located in a configuration file at {Project Folder}\{Config}\DefaultInput.ini.

Input Mappings can be set in the Editor by going to:
Settings > Projects Settings > Engine > Input > Bindings

There are two main types of abstractions that the Engine recognises by default:

  • Action Mappings
  • Axis Mappings

Action Mappings provide a digital (pressed/released) abstraction for controller actions such as button clicks, triggers clicks, etc.

Axis Inputs provide a Vector1 (float) abstraction for controller actions such as Trigger Axis, Thumbstick X Location, Thumbstick Y Location, etc.

It’s important to note here that the X and Y values have outputs that are separate floats ranging from 0 to 1 and not combined as a Vector2

Once Input Actions are mapped, they can then be called in Blueprints like any controller input like so:

More info about Unreal Engine’s Input Abstractions can be found here:


Similar to Unreal’s built-in Input Abstraction, SteamVR’s new Input System provides a similar, although broader, abstraction system to help support multiple controller types as well as give end-users the ability to remap controller input-to-action “bindings” to suit their particular game style.

As with Unreal Engine’s DefaultInput.ini file, these mappings are defined in external files:

1. Action Manifest

The Action Manifest is a json file which provides the Steam Input System with information on what “actions” (e.g. Teleport, Grab) are available in your VR Experience/Game, the location of Controller “Input Profiles” which contain the actual controller input-to-action binding definitions for that particular controller, action sets to help group actions together and their mapping behaviour for end users and a section for localizing the names of actions to different languages and dialects.

Let’s look at each section more closely:

Actions — This is where the name of each individual action or mechanic in your VR Game/Experience is defined and their expected input value (e.g. Boolean, Vector1, Vector2, etc):

Default Bindings — Defines where the Controller Input Profile (controller input-to-action) are located for each type of controller supported by your VR Experience/Game:

Action Sets — Allows you to group actions together and control their behaviour in SteamVR’s Input Binding UI in one of the following ways:

  • leftright — Allows users of your VR Experience/Game to individually bind actions to either of the left and right controllers.
  • single — Bindings created by the user on one controller gets automatically mirrored to the other controller.
  • hidden — This is an action set that allows developers to hide hide actions from users so the action can’t be rebound.

Localization — Allows you to provide translations for your actions to different languages and dialects in the form of “{iso 639–1}-{iso 3166–1}” (?)

All action text defaults to English if a specific language isn’t defined, so it’s best to always define the English equivalents at the very least if your VR Experience/Game uses non-English action names.

For more information about the Action Manifest file, you can check full documentation of it here:

2. Controller “Input Profile” Binding Files

These are json files that map a controller input to particular action(s) in your VR Experience/Game.

Each controller supported by your VR Experience/Game will need one Controller Input Profile setup for it. The Input Profile set up looks like this:

Understanding how to generate your own definitions is critical in UE4.21 as these aren’t populated for you by default, we will look at this in better detail at Chapter n

For more information about the Controller Input Profiles, the official documentation can be found here:


To begin using the new Steam Input System for your VR Experience/Game, you need to ensure your project:

  • Has the SteamVR Plugin enabled, and
  • You are using Unreal’s Input Mappings

Once your project is ready for Steam’s new Input System, you can enable this feature by adding a setting the CVar vr.SteamVR.EnableVRInput from 0 to 1 in your DefaultEngine.ini file, located in <location>.

The following sections shows how to do this step-by-step:

1. Enable the SteamVR Plugin
Settings > Plugins > Built-in > Virtual Reality > SteamVR — [add a note about checking the box next to “enabled”]

2. Ensure your project uses Action and/or Axis Mappings for Input

Check this under Settings > Project Settings > Engine > Input > Bindings

3. Enable UE4.21’s SteamVR Input System Support
Add the following lines to your DefaultEngine.ini file ({Your Project Directory}\Config\DefaultEngine.ini):



And that’s it! You’re all set! SteamVRInput is now be enabled in your project.


With the new SteamVRInput System enabled, the Engine will generate the following files at runtime, both for Editor and Packaged Builds:

SteamVR Input Action Manifest
{Your Project Directory}\Saved\Config\steamvr_actions.json

SteamVR Input Profile “Binding” Files (as stubs)

{Your Project Directory}\Config\SteamVRBindings\{controller-type}.json

The action manifest (steamvr_actions) file UE 4.21 generates uses the action set “/actions/main” with action definitions from your project’s Input Key and Axis Mappings (See Chapter n).

This file is auto-generated each time your application runs .

Axis mapping actions are postpended with “_axis” which takes in a float (Vector1). If both X and Y axes for an input controller have been defined, an additional action definition is generated by the Engine. This definition is postpended with “_axis2d”, which expects a Vector2 value to return to the Engine.

Axis Mappings as they are set in UE
The generated actions in the Action Manifest (steamvr_actions.json) file

The Controller Input Profile Binding files which are generated by UE4.21 are merely stubs and the raw controller input-to-action mappings can be set using SteamVR’s Controller Input Binding UI, find under:

SteamVR > Devices > Controller Input Binding > UE4Edtior.exe

It is recommended to restart SteamVR if you have changed your action mappings and/or bindings to ensure the information in your manifest is properly replicated to the SteamVR Input system.


While UE 4.21 generates a complete action manifest and Controller Input Profile Binding Files for common SteamVR controller types:

  • Gamepad
  • Holographic Controller
  • Oculus Touch
  • Vive (Headset only)
  • Vive Controller

These Controller Binding files are only stubs and does not include any input to action definitions.

You need to either use SteamVR’s Controller Input Dashboard:

You can also enable debug mode for this dashboard:

{Screenshots here}

OR setup your own Binding Files especially for Controller Types that aren’t generated by UE 4.21 automatically (e.g. Knuckles).

Plugins such as Project SunRock (link) and the upcoming official SteamVR Input plugin (announcement link) auto-generates these files for you and closes this functional gap left by UE4.21.

To help in creating your own Input Binding File, below is its General Structure:

The “Bindings” section is further split into the following subsections:

There are also subsections for Chords and Poses which are not covered by this article.

More information on these can be found in the official documentation:


1. Prerequisites

To define your own raw controller input to actions, ensure that the Input Profile file (See Chapter n) you are editing is properly declared in the Action Manifest:

For UE 4.21, the Action Manifest is auto-generated at:
{Your Project Directory}\Saved\Config\steamvr_actions.json

For Builds, if you’ve made edits to this file, make sure that you copy over this revised Action Manifest to your Build and not rely on the runtime auto-generation.

2. Defining the Input-to-Action Mappings

Once you’ve made sure that the Input Profile file you are editing/creating is defined in the Action Manifest, it’s time to make the action mappings for this controller.

First let’s have a look at the General Structure of an input to action definition in an Input Profile file:

  1. This is the Action Set where the action mappings belong to.
  2. This is an Array of input sources with each json object defining the Input Mode (see next section) and input path recognised by the SteamVR Input System.
  3. Definition of the raw controller input which includes the following valid Input Modes and Paths:

Joystick (also used for thumbsticks)





4. This is an array of json objects that define for a particular Input Mode, which Action is triggered by an Input Type.

5. This the json object which links an Input Type to an Action. Available Input Types with their corresponding output values for each Input Mode are:

  • Joystick (also used for thumbsticks)
  • Position (vector2)
  • Click (boolean)
  • Touch (boolean)
  • Trackpad
  • Click (boolean)
  • Touch (boolean)
  • Position (vector2)
  • Trigger
  • Pull (vector1)
  • Click (boolean)
  • Touch (boolean)
  • Button
  • Click (boolean)
  • Touch (boolean)
  • Force_Sensor
  • Force

3. Samples

Below are samples of common Input Mappings to help you along:

Trigger Pull (Vector1)

Click (Boolean)

Position (Vector2)

Force Sensor (Vector 1)

For these and more samples you can check the following file:

4. Haptics

Haptic mappings are mapped (as long as there is a valid action defined in the Action Manifest for it) using the following convention:

As you can see, this is simply a json array of the Action name defined as an OUTPUT and valid SteamVR input path.

This is defined in the same level as the sources in the Input Profile file:

5. Skeletal Anim

If the controller you are defining actions to have Skeletal Animation support, you can map them like so:

Similar to Haptics, the mappings is a json array of the SteamVR action defined as an OUTPUT and a valid input path.

This json object is defined in the same level as the Haptics:

The full sample file can be taken from here:


Project SunRock provides native support for Knuckles controllers including Skeletal Animation via a custom LiveLink source and extends the current UE4.21 SteamVR Controller Implementation by adding autogeneration of Controller Input Profiles from the action and axis mappings defined in your project.

The custom Plugin behind Project SunRock contain the following core modules:

  • Knuckles LiveLink — For livelink feed of SteamVR hand skeletal animation
  • Knuckles LiveLink Runtime — For establishing Livelink Feed during runtime
  • KnucklesVRController BP Library — For static functions related to SteamVRInput (e.g. Triggering Haptics)
  • KnucklesVRController — Reimplemented SteamVRController from UE4.21 to support Knuckles and automated new SteamVR Input Bindings generation.

The project is Open Source under the MIT License and available in GitHub.

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade