# How To's

The following information was written under the assumption that you have already completely read and understood all documentation topics under Essentials and Concepts in the Documentation. If you have not done so, please do before continuing.

Topics:

- Important classes
- Getting a Player
- Getting input
- Getting a Controller
- Receiving Joystick connect and disconnect events
- Assigning Joysticks to players
- Enabling and disabling Controller Maps
- Managing Controller Maps at runtime
- Loading Controller Maps at runtime
- Displaying a button/axis/key name to the user for an Action
- Displaying a glyph for a Joystick element mapped to an Action
- Displaying a glyph for the currently active Joystick elements
- Getting contributing input sources for an Action
- Determining which Controller was last used
- Calibrating Joystick axes
- Vibration/Rumble
- Handling button presses of various types
- Handling multi-button Actions
- Excluding certain Players from Joystick auto-assignment
- Changing configuration settings at runtime
- Converting scripts from UnityEngine.Input to Rewired
- Exporting constants for use in scripting
- Displaying a drop-down list of Actions in the inspector of a script
- Implementing a "Press Start to Join" Joystick assignment system
- Saving and loading Controller Maps
- Saving and loading Calibration Maps
- Modifying Input Behaviors during runtime
- Creating on-screen touch controllers
- Creating a controller mapping screen
- Creating new controller definitions
- Creating new controller templates
- Adding a controller to an existing controller template
- Excluding controller definitions
- Identifying recognized Joysticks by type
- Identifying controllers on Windows fallback or Windows Webplayer platforms
- Hiding input settings on the Unity launcher
- Optimizing performance
- Using Rewired to control Unity's new UI
- Using Apple Siri Remote on Apple TV
- Using ArcadeGuns G-500 AimTrak Light Guns
- Using Sony DualShock 4 special features
- Using P.I. Engineering Rail Driver special features
- Using XBox One controller special features on XBox One platform
- Using PS4 gamepad special features on PS4 platform

### Important classes

Rewired's API has been organized using helper classes to group methods and properties topically. This makes it easier to find the methods you are looking for through the IDE.

Global Information:

- ReInput - The main class for accessing all input-related information.
- ReInput.players - Players and Player-related information.
- ReInput.controllers - Controllers and controller-related information of all types.
- ReInput.mapping - Controller Map, Action, Input Behavior and other data in the Rewired Input Manager.

Player-Related Information:

- Player - Get input from the Player.
- Player.controllers - All Controller-related information in a Player.
- Player.controllers.maps - All Controller Map-related information in a Player.

More classes are listed in the API reference.

### Getting a Player

Get a Player by id or name through ReInput.players.GetPlayer

More methods for accessing Players: ReInput.players

    using UnityEngine;
    using Rewired;

    public class MyClass : MonoBehaviour {
        public int playerId;
        private Player player;

        void Awake() {
            // Get the Player for a particular playerId
            player = ReInput.players.GetPlayer(playerId);

           // Some more examples:

           // Get the System Player
           Player systemPlayer = ReInput.players.GetSystemPlayer();

           // Iterating through Players (excluding the System Player)
           for(int i = 0; i < ReInput.players.playerCount; i++) {
               Player p = ReInput.players.Players[i];
           }

           // Iterating through Players (including the System Player)
           for(int i = 0; i < ReInput.players.allPlayerCount; i++) {
               Player p = ReInput.players.AllPlayers[i];
           }
        }
    }

### Getting input

There are two primary ways to get input in Rewired:

1. Polling for input - This is the most common method and is very similar to how you normally get input in Unity.
2. Using input events - This method allows you to get input by registering for an event and receving a callback when that event takes place.

Polling Method:

Get input through the Player class.

Rewired mirrors Unity's method nomenclature for getting input values:

- Player.GetButton - Gets the button held state of an Action. This will return TRUE as long as the button is held. This also applies to axes being used as buttons.
- Player.GetButtonDown - Gets the button just pressed state of an Action. This will only return TRUE only on the first frame the button is pressed or for the duration of the Button Down Buffer time limit if set in the Input Behavior assigned to this Action. This also applies to axes being used as buttons.
- Player.GetButtonUp - Get the button just released state for an Action. This will only return TRUE for the first frame the button is released. This also applies to axes being used as buttons.
- Player.GetAxis - Gets the axis value of an Action.
- There are many more methods available in the Player class.

All Actions can be queried for Button or Axis value regardless of the underlying hardware mapped to that Action.

    using UnityEngine;
    using Rewired;

    public class MyClass : MonoBehaviour {
        public int playerId;
        private Player player;

        void Awake() {
            player = ReInput.players.GetPlayer(playerId);
        }

        void Update() {
            if(player.GetAxis("Move Horizontal") != 0.0f) {
                Debug.Log("Move Horizontal!");
            }

            if(player.GetButtonDown("Fire")) {
                Debug.Log("Fire!");
            }
        }
    }

Event Method:

Use delegates to receive input events from a Player. There are numerous overloads available that allow you to register to receive events on different update loops, for specific input event types, and for specific Actions. For a list of event types and whether they require additional arguments, see InputActionEventType.

    public class MyClass : MonoBehaviour {
        public int playerId;
        private Player player;

        void Awake() {
            player = ReInput.players.GetPlayer(playerId);

            // Add delegates to receive input events from the Player

            // This event will be called every frame any input is updated
            player.AddInputEventDelegate(OnInputUpdate, UpdateLoopType.Update);

            // This event will be called every frame the "Fire" action is updated
            player.AddInputEventDelegate(OnFireUpdate, UpdateLoopType.Update, "Fire");

            // This event will be called when the "Fire" button is first pressed
            player.AddInputEventDelegate(OnFireButtonDown, UpdateLoopType.Update, InputActionEventType.ButtonJustPressed, "Fire");

            // This event will be called when the "Fire" button is first released
            player.AddInputEventDelegate(OnFireButtonUp, UpdateLoopType.Update, InputActionEventType.ButtonJustReleased, "Fire");

            // This event will be called when the "Jump" button is held for at least 2 seconds and then released
            player.AddInputEventDelegate(OnJumpButtonUp, UpdateLoopType.Update, InputActionEventType.ButtonPressedForTimeJustReleased, "Jump", new object[] { 2.0f });

            // The update loop you choose for the event matters. Make sure your chosen update loop is enabled in
            // the Settings page of the Rewired editor or you won't receive any events.
        }

        void OnInputUpdate(InputActionEventData data) {
            switch(data.actionName) { // determine which action this is
                case "Move Horizontal":
                    if(data.GetAxis() != 0.0f) Debug.Log("Move Horizontal!");
                    break;
                case "Fire":
                    if(data.GetButtonDown()) Debug.Log("Fire!");
                    break;
            }
        }

        void OnFireUpdate(InputActionEventData data) {
            if(data.GetButtonDown()) Debug.Log("Fire!");
        }

        void OnFireButtonDown(InputActionEventData data) {
            Debug.Log("Fire!");
        }

        void OnFireButtonUp(InputActionEventData data) {
            Debug.Log("Fire Released!");
        }

        void OnJumpButtonUp(InputActionEventData data) {
            Debug.Log("Jump!");
        }
    }

Controller Method:

A third method would be to get input directly from a Controller's buttons and axes. This is generally not the best choice as you will lose all the advantages of the player-centric system including mapping. Methods for accessing element values can be found in the respective Controller classes:

- Joystick
- Keyboard
- Mouse
- Custom Controller

    void LogMouseValues() {
        Mouse mouse = ReInput.controllers.Mouse;
        Debug.Log("Left Mouse Button = " + mouse.GetButton(0));
        Debug.Log("Right Mouse Button (Hold) = " + mouse.GetButton(1));
        Debug.Log("Right Mouse Button (Down) = " + mouse.GetButtonDown(1));
        Debug.Log("Right Mouse Button (Up) = " + mouse.GetButtonUp(1));
    }

    void LogPlayerJoystickValues(Player player) {
        // Log the button and axis values for each joystick assigned to this Player
        for(int i = 0; i < player.joystickCount; i++) {
            Joystick joystick = player.Joysticks[i];
            Debug.Log("Joystick " + i + ":");
            LogJoystickElementValues(joystick); // log all the element values in this joystick
        }
    }

    void LogJoystickElementValues(Joystick joystick) {
        // Log Joystick button values
        for(int i = 0; i < joystick.buttonCount; i++) {
            Debug.Log("Button " + i + " = " + joystick.Buttons[i].value); // get the current value of the button
        }

        // Log Joystick axis values
        for(int i = 0; i < joystick.axisCount; i++) {
            Debug.Log("Axis " + i + " = " + joystick.Axes[i].value); // get the current value of the axis
        }
    }

### Getting a Controller

You generally don't need to get Controllers for normal gameplay input tasks, but there are certain times when you need to get a Controller such as during Controller remapping. There are a number of ways you can get Controllers.

To get a specific controller:
ReInput.controllers.GetController
player.controllers.GetController
player.controllers.GetControllerWithTag

You can get the mouse from:
ReInput.controllers.Mouse
player.controllers.Mouse

You can get the keyboard from:
ReInput.controllers.Keyboard
player.controllers.Keyboard

You can loop through all controllers:
ReInput.controllers.Controllers
ReInput.controllers.Joysticks
ReInput.controllers.CustomControllers

You can loop through controllers assigned to a Player:
player.controllers.Joysticks
player.controllers.CustomControllers

### Receiving Joystick connect and disconnect events

To receive an event when a Joystick is connected, register for ReInput.ControllerConnectedEvent.
To receive an event when a Joystick is fully disconnected, register for ReInput.ControllerDisconnectedEvent.
To receive an event when a Joystick is about to be disconnected, register for ReInput.ControllerPreDisconnectEvent.

Note: Joysticks are not guaranteed to be available on Awake or Start on all platforms or input sources. If Joysticks are available immediately to Rewired on Awake, Joystick connected events will not be sent. If Joystick availability is delayed, a Controller connected event will be sent when Rewired detects the controller. If you need to check for the presence of Joysticks at the beginning of your game, you should always check in both Awake or Start and by subscribing to the ReInput.ControllerConnectedEvent.

    using UnityEngine;
    using Rewired;

    public MyClass : MonoBehaviour {

        void Awake() {
            ReInput.ControllerConnectedEvent += OnControllerConnected;
            ReInput.ControllerDisconnectedEvent += OnControllerDisconnected;
            ReInput.ControllerPreDisconnectEvent += OnControllerPreDisconnect;
        }

        // This function will be called when a controller is connected
        // You can get information about the controller that was connected via the args parameter
        void OnControllerConnected(ControllerStatusChangedEventArgs args) {
            Debug.Log("A controller was connected! Name = " + args.name + " Id = " + args.controllerId + " Type = " + args.controllerType);
        }

         // This function will be called when a controller is fully disconnected
         // You can get information about the controller that was disconnected via the args parameter
         void OnControllerDisconnected(ControllerStatusChangedEventArgs args) {
            Debug.Log("A controller was disconnected! Name = " + args.name + " Id = " + args.controllerId + " Type = " + args.controllerType);
        }

         // This function will be called when a controller is about to be disconnected
         // You can get information about the controller that is being disconnected via the args parameter
         // You can use this event to save the controller's maps before it's disconnected
         void OnControllerPreDisconnect(ControllerStatusChangedEventArgs args) {
            Debug.Log("A controller is being disconnected! Name = " + args.name + " Id = " + args.controllerId + " Type = " + args.controllerType);
        }
    }

### Assigning Joysticks to players

Joysticks will be assigned to Players automatically if you have enabled and configured Joystick auto-assignment in the Rewired Editor under Settings. However, if you wish to manually assign or unassign Joysticks, you can do so with the following methods:

Player class:

- player.controllers.AddController
- player.controllers.RemoveController
- player.controllers.ContainsController
- player.controllers.ClearControllersOfType
- player.controllers.ClearAllControllers

ReInput class:

- ReInput.controllers.IsControllerAssigned
- ReInput.controllers.IsControllerAssignedToPlayer
- ReInput.controllers.RemoveControllerFromAllPlayers
- ReInput.controllers.AutoAssignJoystick
- ReInput.controllers.AutoAssignJoysticks

Also, see Receiving joystick connect and disconnect events to get a notification when a Joystick is connected or disconnected.

    // Example: Shows how to assign Joysticks manually to the next Player that doesn't have one assigned.

    void Awake() {
        // Listen for controller connection events
        ReInput.ControllerConnectedEvent += OnControllerConnected;

        // Assign each Joystick to a Player initially
        foreach(Joystick j in ReInput.controllers.Joysticks) {
            if(ReInput.controllers.IsJoystickAssigned(j)) continue; // Joystick is already assigned

            // Assign Joystick to first Player that doesn't have any assigned
            AssignJoystickToNextOpenPlayer(j);
        }
    }

    // This will be called when a controller is connected
    void OnControllerConnected(ControllerStatusChangedEventArgs args) {
        if(args.controllerType != ControllerType.Joystick) return; // skip if this isn't a Joystick

        // Assign Joystick to first Player that doesn't have any assigned
        AssignJoystickToNextOpenPlayer(ReInput.controllers.GetJoystick(args.controllerId));
    }

    void AssignJoystickToNextOpenPlayer(Joystick j) {
        foreach(Player p in ReInput.players.Players) {
            if(p.controllers.joystickCount > 0) continue; // player already has a joystick
            p.controllers.AddController(j, true); // assign joystick to player
            return;
        }
    }

You can also use the joystick auto-assign system to automatically assign certain Joysticks while excluding others:

    // Joystick Auto-Assignment is disabled in the Rewired Input Manager, but you can still use it to
    // assign one or all Joysticks at any time.

    void OnControllerConnected(ControllerStatusChangedEventArgs args) {
        if(args.controllerType != ControllerType.Joystick) return; // skip if this isn't a Joystick

        // Get the Joystick from ReInput
        Joystick joystick = ReInput.controllers.GetJoystick(args.controllerId);
        if(joystick == null) return;

        // Exclude the Apple Siri Remote -- it will be left unassigned
        // The Siri Remote's Hardware Type Guid is bc043dba-df07-4135-929c-5b4398d29579
        // See this for more information on Hardware Type GUID.
        if(joystick.hardwareTypeGuid == new System.Guid("bc043dba-df07-4135-929c-5b4398d29579")) return;

        // Assign Joystick to first Player that doesn't have any assigned
        ReInput.controllers.AutoAssignJoystick(joystick);
    }

### Enabling and disabling Controller Maps

Controller Maps can be enabled or disabled at will via scripting. This can be useful if you want to change game modes and have a different set of controls become active. For example, opening a menu screen. Disabled Controller Maps will not return any value when the Player is queried for an Action's input value. Controller Maps are stored in the Player class.

The easiest way to enable and disable maps in a Player is to use the following methods:

- player.controllers.maps.SetAllMapsEnabled - Set enabled state on all maps owned by the Player or all maps for a specific Controller type.
- player.controllers.maps.SetMapsEnabled - Set enabled state on a group of maps owned by the Player by Controller type, Map Category, and Layout.

Example: Set enabled state on all of a Player's Controller Maps in a certain Map Category for all Controller types with one line of code.

    // The quick way - one line of code
    player.controllers.maps.SetMapsEnabled(state, categoryName);

NOTE: The above SetMapsEnabled and SetAllMapsEnabled methods are not persistent flags in Player that will set a certain category of map enabled/disabled upon loading. They are simply shortcuts for the below methods that iterate the maps currently loaded in the Player and set them enabled/disabled at the time the method is called. When new Controller Maps are loaded in the Player, either manually or when a Joystick is assigned, the newly loaded maps will be enabled/disabled based on the default enabled state settings for these maps on the Player page in the Rewired Input Manager, not based on previous calls to SetMapsEnabled.

You can also enable and disable maps one by one by getting the maps one by one:

- player.controllers.maps.GetMap
- player.controllers.maps.GetMaps
- player.controllers.maps.GetAllMaps
- player.controllers.maps.GetAllMapsInCategory

Once you have the map, enable or disable it by setting controllerMap.enabled = true or controllerMap.enabled = false. Disabled maps will not contribute to input.

Example: Set enabled state on all of a Player's Controller Maps in a certain Map Category for all Controller types one by one.

    // The manual way - iterate all Controller Maps in a category and set the state manually
    foreach(ControllerMap map in player.controllers.maps.GetAllMapsInCategory(categoryName)) {
        map.enabled = state; // set the enabled state on the map
    }

### Managing Controller Maps at runtime

Controller Maps can be added, removed, cleared, and reloaded during gameplay via scripting. This can be useful if you want to load the default Controller Maps as defined in the Rewired Editor after having made changes, or to load a Controller Map in a different Layout. Controller Maps are stored in the Player class.

Methods:

- player.controllers.maps.AddMap
- player.controllers.maps.RemoveMap
- player.controllers.maps.ClearAllMaps
- player.controllers.maps.ClearMaps
- player.controllers.maps.LoadMap
- player.controllers.maps.LoadDefaultMaps
- More methods for controller map management

Each Controller Map contains a list of Action Element Maps, which bind Actions to a specific elements on a Controller. Each ActionElementMap represents one binding. The various properties of the ActionElementMap determine the specifics of the binding, such as the elementType and elementIndex.

    // Iterate over all Mouse Maps assigned to this Player and log the element type and index for each ActionElementMap
    foreach(var controllerMap in player.controllers.maps.GetMaps(ControllerType.Mouse, 0)) {
        foreach(var actionElementMap in controllerMap.AllMaps) { // iterate over all maps regardless of type
            InputAction action = ReInput.mapping.GetAction(actionElementMap.actionId); // get the Action from the binding

            // Log the element type, element index, and the Action name
            Debug.Log(actionElementMap.elementType + " " + actionElementMap.elementIndex + " is bound to " + (action != null ? action.name : "nothing"));
        }
    }

### Loading Controller Maps at runtime

Before a Player can use a Controller Map, it first must be loaded into that Player. Controller Maps are loaded for each Player automatically at start (or, in the case of Joysticks, they are loaded when a Joystick is assigned to the Player) based on the Controller Map assignments you've made in the Players page of the Rewired Input Manager.

To assign the Controller Map at runtime via scripting or reload a default map (for example if you want to revert controls to the defaults), you would use the following methods to load a default Controller Map from the Rewired Input Manager into a Player.

Methods:

- player.controllers.maps.LoadMap
- player.controllers.maps.LoadDefaultMaps

These methods load the Controller Maps you've created in the Rewired Input Manager into the Player. You can load Controller Maps that have not been assigned to the Player in the Rewired Input Manager or replace existing Controller Maps that are already assigned. Documentation about each overload can be found in the method links above.

    // Re-load the keyboard maps that were assigned to this Player in the Rewired Input Manager
    player.controllers.maps.LoadDefaultMaps(ControllerType.Keyboard);

    // Load joysticks maps in each joystick in the "UI" category and "Default" layout and set it to be enabled on start
    foreach(Joystick joystick in player.controllers.Joysticks) {
        player.controllers.maps.LoadMap(ControllerType.Joystick, joystick.id, "UI", "Default", true);
    }

### Displaying a button/axis/key name to the user for an Action

If you want to display some help text on the screen telling the user which button/key/axis to press for a particular Action, you can get this information from the ActionElementMap.elementIdenfitierName property. The following example shows various ways to get this information for an Action.

    Player player = Rewired.ReInput.players.GetPlayer(0);

    // If set to true, only enabled maps will be returned
    bool skipDisabledMaps = true;

    // Get the first ActionElementMap of any type with the Action "Fire"
    Debug.Log(player.controllers.maps.GetFirstElementMapWithAction("Fire", skipDisabledMaps).elementIdentifierName);

    // Get the first button map with the Action "Jump"
    Debug.Log(player.controllers.maps.GetFirstButtonMapWithAction("Jump", skipDisabledMaps).elementIdentifierName);

    // Get the first axis map with the Action "Move Horizontal"
    Debug.Log(player.controllers.maps.GetFirstAxisMapWithAction("Move Horizontal", skipDisabledMaps).elementIdentifierName);

    // Loop over all ActionElementMaps of any type with the Action "Fire"
    foreach(var aem in player.controllers.maps.ElementMapsWithAction("Fire", skipDisabledMaps)) {
        Debug.Log(aem.elementIdentifierName);
    }

    // Loop over all button maps with the Action "Fire"
    foreach(var aem in player.controllers.maps.ButtonMapsWithAction("Fire", skipDisabledMaps)) {
        Debug.Log(aem.elementIdentifierName);
    }

    // Loop over all Axis maps with the Action "Move Horizontal"
    foreach(var aem in player.controllers.maps.AxisMapsWithAction("Move Horizontal", skipDisabledMaps)) {
        Debug.Log(aem.elementIdentifierName);
    }

    // All elements mapped to all joysticks in the player
    foreach(Joystick j in player.controllers.Joysticks) {

        // Loop over all Joystick Maps in the Player for this Joystick
        foreach(JoystickMap map in player.controllers.maps.GetMaps(j.id)) {

            // Loop over all button maps
            foreach(ActionElementMap aem in map.ButtonMaps) {
                Debug.Log(aem.elementIdentifierName + " is assigned to Button " + aem.elementIndex + " with the Action " + ReInput.mapping.GetAction(aem.actionId).name);
            }

            // Loop over all axis maps
            foreach(ActionElementMap aem in map.AxisMaps) {
                Debug.Log(aem.elementIdentifierName + " is assigned to Axis " + aem.elementIndex + " with the Action " + ReInput.mapping.GetAction(aem.actionId).name);
            }

            // Loop over all element maps of any type
            foreach(ActionElementMap aem in map.AllMaps) {
                if(aem.elementType == ControllerElementType.Axis) {
                    Debug.Log(aem.elementIdentifierName + " is assigned to Axis " + aem.elementIndex + " with the Action " + ReInput.mapping.GetAction(aem.actionId).name);
                } else if(aem.elementType == ControllerElementType.Button) {
                    Debug.Log(aem.elementIdentifierName + " is assigned to Button " + aem.elementIndex + " with the Action " + ReInput.mapping.GetAction(aem.actionId).name);
                }
            }
        }
    }

    // Log the keyboard keys assigned to an Action manually
    foreach(ActionElementMap aem in player.controllers.maps.ButtonMapsWithAction(ControllerType.Keyboard, "ActionName", false)) {
        InputAction action = ReInput.mapping.GetAction(aem.actionId);
        if(action == null) continue; // invalid Action
        if(aem.keyCode == KeyCode.None) continue; // there is no key assigned

        string descriptiveName = action.descriptiveName; // get the descriptive name of the Action

        // Create a string name that contains the primary key and any modifier keys
        string key = aem.keyCode.ToString(); // get the primary key code as a string
        if(aem.modifierKey1 != ModifierKey.None) key += " + " + aem.modifierKey1.ToString();
        if(aem.modifierKey2 != ModifierKey.None) key += " + " + aem.modifierKey2.ToString();
        if(aem.modifierKey3 != ModifierKey.None) key += " + " + aem.modifierKey3.ToString();

        // Treat axis-type Actions differently than button-type Actions because axis contribution could be positive or negative
        // It's generally safe to assume positive contribution for button-type Actions
        if(action.type == InputActionType.Axis) { // this is an axis-type Action

            // Determine if it contributes to the positive or negative value of the Action
            if(aem.axisContribution == Pole.Positive) { // positive
                descriptiveName = !string.IsNullOrEmpty(action.positiveDescriptiveName) ?
                    action.positiveDescriptiveName :  // use the positive name if one exists
                    action.descriptiveName + " +"; // use the descriptive name with sign appended if not
            } else { // negative
                descriptiveName = !string.IsNullOrEmpty(action.negativeDescriptiveName) ?
                    action.negativeDescriptiveName :  // use the negative name if one exists
                    action.descriptiveName + " -"; // use the descriptive name with sign appended if not
            }
        }

        Debug.Log(descriptiveName + " is assigned to " + key);
    }

### Displaying a glyph for a Joystick element mapped to an Action

There are three steps involved in displaying on-screen glyphs for Joystick elements:

1. Create the Joystick element glyph graphics.
2. Create a lookup table of Joystick element glyphs.
3. Display the glyph on-screen.

Step 1:
Obviously this is up to you to decide how your glyphs will look and in what data format they will be in.

Step 2:
You will need to create a lookup table that associates particular Element Identifiers from particular Joysticks to the glyphs. This could be in any format you choose -- a database lookup, serialized data in a MonoBehaviour, etc.

This would look something like this in concept:

Joystick | Guid | Element Identifier | Glyph
Xbox 360 Controller | d74a350e-fe8b-4e9e-bbcd-efff16d34115 | 0 | 360_LeftStick_Horiz
|  | 1 | 360_LeftStick_Vert
|  | 6 | 360_ButtonA

Step 3:
Display the glyph on screen. This is up to you however you choose to do so depending on your data format and needs.

You can retrieve the glpyh based on the Joystick's GUID and the current Element Identifier Id mapped to a particular Action.

Here are the basic steps:

1. Get the last used Controller from the Player using Player.controllers.GetLastActiveController.
2. Determine the type of the Controller using the Controller.type property.
3. If a Joystick, identify this Joystick as a recognized type using the Joystick.hardwareTypeGuid property. (The type GUID for each recognized Controller can be found in the HardwareJoystickMap definition for each Controller on the Settings page.)
4. Check if any element on this Controller is mapped to the Action in question using one of the following methods:
   - Player.controllers.maps.GetFirstElementMapWithAction
   - Player.controllers.maps.GetFirstButtonMapWithAction
   - Player.controllers.maps.GetFirstAxisMapWithAction
   - Player.controllers.maps.ElementMapsWithAction
   - Player.controllers.maps.ButtonMapsWithAction
   - Player.controllers.maps.AxisMapsWithAction
5. If the element is mapped, use this information to look up the glyph from your lookup table using the ActionElementMap.elementIdentifierId property and the Joystick.hardwareTypeGuid property.
6. Optional: Further information about the mapping can be found in the ActionElementMap such as the Axis Range, Axis Contribution, type, or other useful information should you need more specific glyphs for a finer level of detail.

Below is a basic example that shows both one method of storing the glyph lookup data and how to get the current element glyph for an Action.

    // ShowControllerGlyphs.cs
    using UnityEngine;
    using System.Collections;

    namespace Rewired.Demos {

        // Shows how to display a glyph for an Action based on the current controller the player is using
        public class ShowControllerGlyphs : MonoBehaviour {

            public string showGlyphHelpForAction;

            // Using OnGUI for Unity 4.3 compatibility
            // You would probably want to use Unity UI in 4.6+ instead
            void OnGUI() {
                ShowGlyphs();
            }

            void ShowGlyphs() {
                // Get the Rewired Player
                Player p = ReInput.players.GetPlayer(0); // just use Player 0 in this example

                // Get the last active controller the Player was using
                Controller activeController = p.controllers.GetLastActiveController();
                if(activeController == null) { // player hasn't used any controllers yet
                    // No active controller, set a default
                    if(p.controllers.joystickCount > 0) { // try to get the first joystick in player
                        activeController = p.controllers.Joysticks[0];
                    } else { // no joysticks assigned, just get keyboard
                        activeController = p.controllers.Keyboard;
                    }
                }

                // Display glyph help for a fixed Action - UI Help example
                if(!string.IsNullOrEmpty(showGlyphHelpForAction)) {
                    InputAction action = ReInput.mapping.GetAction(showGlyphHelpForAction); // get the Action for the current string
                    if(action != null) { // make sure this is a valid action
                        ShowGlyphHelp(p, activeController, action);
                    }
                }
            }

            void ShowGlyphHelp(Player p, Controller controller, InputAction action) {
                if(p == null || controller == null || action == null) return;

                // Find the first element mapped to this Action on this controller
                ActionElementMap aem = p.controllers.maps.GetFirstElementMapWithAction(controller, action.id, true);
                if(aem == null) return; // nothing was mapped on this controller for this Action

                if(controller.type != ControllerType.Joystick) return; // this example only supports joystick glyphs

                // Find the glyph for the element on the controller
                Sprite glyph = ControllerGlyphs.GetGlyph((controller as Joystick).hardwareTypeGuid, aem.elementIdentifierId, aem.axisRange);
                if(glyph == null) return; // no glyph found

                // Draw the glyph to the screen
                Rect rect = new Rect(0, 30, glyph.textureRect.width, glyph.textureRect.height);
                GUI.Label(new Rect(rect.x, rect.y + rect.height + 20, rect.width, rect.height), action.descriptiveName);
                GUI.DrawTexture(rect, glyph.texture);
            }
        }
    }

    // ControllerGlpyhs.cs
    using UnityEngine;
    using System.Collections;

    namespace Rewired.Demos {
        using Rewired.Data.Mapping;

        // This is a basic example showing one way of storing glyph data for Joysticks
        public class ControllerGlyphs : MonoBehaviour {

            [SerializeField]
            private ControllerEntry[] controllers;

            private static ControllerGlyphs Instance;

            void Awake() {
                Instance = this; // set up a singleton
            }

            public static Sprite GetGlyph(System.Guid joystickGuid, int elementIdentifierId, AxisRange axisRange) {
                if(Instance == null) return null;
                if(Instance.controllers == null) return null;

                // Try to find the glyph
                for(int i = 0; i < Instance.controllers.Length; i++) {
                    if(Instance.controllers[i] == null) continue;
                    if(Instance.controllers[i].joystick == null) continue; // no joystick assigned
                    if(Instance.controllers[i].joystick.Guid != joystickGuid) continue; // guid does not match
                    return Instance.controllers[i].GetGlyph(elementIdentifierId, axisRange);
                }

                return null;
            }

            [System.Serializable]
            private class ControllerEntry {
                public string name;
                public HardwareJoystickMap joystick;
                public GlyphEntry[] glyphs;

                public Sprite GetGlyph(int elementIdentifierId, AxisRange axisRange) {
                    if(glyphs == null) return null;
                    for(int i = 0; i < glyphs.Length; i++) {
                        if(glyphs[i] == null) continue;
                        if(glyphs[i].elementIdentifierId != elementIdentifierId) continue;
                        return glyphs[i].GetGlyph(axisRange);
                    }
                    return null;
                }
            }

            [System.Serializable]
            private class GlyphEntry {
                public int elementIdentifierId;
                public Sprite glyph;
                public Sprite glyphPos;
                public Sprite glyphNeg;

                public Sprite GetGlyph(AxisRange axisRange) {
                    switch(axisRange) {
                        case AxisRange.Full: return glyph;
                        case AxisRange.Positive: return glyphPos != null ? glyphPos : glyph;
                        case AxisRange.Negative: return glyphNeg != null ? glyphNeg : glyph;
                    }
                    return null;
                }
            }
        }
    }

### Displaying a glyph for the currently active Joystick elements

Very similar to the previous example, this is a slightly modified process:

    using UnityEngine;
    using System.Collections;

    namespace Rewired.Demos {

        public class ShowControllerGlyphs : MonoBehaviour {

            // Using OnGUI for Unity 4.3 compatibility
            // You would probably want to use Unity UI in 4.6+ instead
            void OnGUI() {
                ShowGlyphs();
            }

            void ShowGlyphs() {
                // Get the Rewired Player
                Player p = ReInput.players.GetPlayer(0); // just use Player 0 in this example

                // Get the last active controller the Player was using
                Controller activeController = p.controllers.GetLastActiveController();
                if(activeController == null) { // player hasn't used any controllers yet
                    // No active controller, set a default
                    if(p.controllers.joystickCount > 0) { // try to get the first joystick in player
                        activeController = p.controllers.Joysticks[0];
                    } else { // no joysticks assigned, just get keyboard
                        activeController = p.controllers.Keyboard;
                    }
                }

                // Display glpyhs for all currently active controller elements
                if(activeController.type != ControllerType.Joystick) return; // this example only shows joysticks, not keyboard/mouse/custom

                int drawCount = 0;

                // Display a glyph for each Action if mapped for this controller in the Player
                for(int i = 0; i < ReInput.mapping.Actions.Count; i++) {
                    ShowActiveActionSource(p, activeController, ReInput.mapping.Actions[i], ref drawCount);
                }
            }

            void ShowActiveActionSource(Player p, Controller controller, InputAction action, ref int count) {

                Joystick joystick = controller as Joystick; // make sure this is a joystick
                if(joystick == null) return;

                float value = p.GetAxis(action.id);
                if(value == 0.0f) return;

                // Find the element source
                if(!p.IsCurrentInputSource(action.id, controller.type, controller.id)) return; // not a source of this action

                // Get the sources contributing to this Action
                var sources = p.GetCurrentInputSources(action.id);
                ActionElementMap aem = null;

                // Find the first source on this controller for the Action
                for(int i = 0; i < sources.Count; i++) {
                    if(sources[i].controller != controller) continue;
                    aem = sources[i].actionElementMap;
                    break; // only show one source for now
                }
                if(aem == null) return;

                // Find the glyph for the element on the controller
                Sprite glyph = ControllerGlyphs.GetGlyph(joystick.hardwareTypeGuid, aem.elementIdentifierId, aem.axisRange);
                if(glyph == null) return; // no glyph found

                // Draw the glyph to the screen
                Rect rect = new Rect(count * 120, 30, glyph.textureRect.width, glyph.textureRect.height);
                GUI.Label(new Rect(rect.x, rect.y + rect.height + 20, rect.width, rect.height), action.descriptiveName);
                GUI.DrawTexture(rect, glyph.texture);

                count++;
            }
        }
    }

### Getting contributing input sources for an Action

You can get information about all the input sources currently contributing to the value of an Action in a Player. There are several methods available to get this information:

- Player.GetCurrentInputSources
- Player.IsCurrentInputSource
- InputActionEventData.GetCurrentInputSource
- InputActionEventData.IsCurrentInputSource

You can either retrieve a list of all input sources currently contributing to input or query whether a Controller type or an individual Controller contributed input.

You can get data about the current input sources and then use that to tell which Controllers or even which individual elements on the Controllers were used to provide the input in the current frame.

See InputActionSourceData for more information on data returned.

### Determining which Controller was last used

You can determine which Controller or what type of Controller was last used system-wide or by an individual Player. One common use of this technique is to switch on-screen glyphs depending on whether the user is using a mouse/keyboard or a Joystick.

Use the following methods:

- ReInput.controllers.GetLastActiveController
- ReInput.controllers.GetLastActiveControllerType
- Player.controllers.GetLastActiveController

The ReInput methods will get the last active controller of all controllers regardless of whether or not it is assigned to a Player or any of the elements have been mapped. This is most useful for one-player games.

The Player.controllers.GetLastActiveController method will get the last active controller used by that Player. Be aware that only mapped elements determine whether a Controller just became active. For example, if you're testing to see if the mouse is the last active controller, if nothing is mapped to the left mouse button and it is clicked, it will not be considered the last active controller in the Player.

Then you can get the Controller type from Controller.type.

    // Get last controller from a Player and the determine the type of controller being used
    Controller controller = player.controllers.GetLastActiveController();
    if(controller != null) {
      switch(controller.type) {
        case ControllerType.Keyboard:
          // Do something for keyboard
          break;
        case ControllerType.Joystick:
          // Do something for joystick
          break;
        case ControllerType.Mouse:
          // Do something for mouse
          break;
        case ControllerType.Custom:
          // Do something custom controller
          break;
      }
    }

You can also subscribe to events instead of polling:

- ReInput.controllers.AddLastActiveControllerChangedDelegate
- ReInput.controllers.RemoveLastActiveControllerChangedDelegate
- ReInput.controllers.ClearLastActiveControllerChangedDelegates
- Player.controllers.AddLastActiveControllerChangedDelegate
- Player.controllers.RemoveLastActiveControllerChangedDelegate
- Player.controllers.ClearLastActiveControllerChangedDelegates

### Calibrating Joystick axes

The general process of calibrating Joystick axes is as follows:

1. Get the Joystick.
2. Get the Calibration Map from the Joystick.
3. Get the AxisCalibration for the Axis from the Calibration Map.
4. Set the calibrated values in the AxisCalibration object.

You can see an example of axis calibration in Rewired/Examples/ControlRemapping1.

Enabled
The enabled state of the Axis can be set with the AxisCalibration.enabled property. Disabled Axes always return 0.

Dead zone
The dead zone of the Axis can be set with the AxisCalibration.deadZone property. If the Axis's absolute value is less than or equal to the dead zone, it will return 0.

Min, max, zero
The Axis's value can be converted to a new range using the AxisCalibration.calibratedMin, AxisCalibration.calibratedMax, and AxisCalibration.calibratedZero properties. These can be used to transform the value of an Axis such as a gamepad trigger that returns -1 at a resting state into a more useful range of 0 when at rest, 1 when fully pressed. If AxisCalibration.applyRangeCalibration is set to false, these transformations will not be applied.

Invert
If AxisCalibration.invert is set to true, the final value will be multiplied by -1. This can be used to correct an inverted Axis.

Sensitivity
In order to set axis sensitivity, you must set the AxisCalibration.sensitivityType to determine how it will be calculated. If AxisCalibration.sensitivityType is set to Multiplier or Power, the AxisCalibration.sensitivity property is used to calculate the value. If AxisCalibration.sensitivityType is set to Curve, the AxisCalibration.sensitivityCurve property is used to calculate the value.

Useful API Reference:

CalibrationMap
AxisCalibration
AxisCalibrationData
Joystick.calibrationMap
CalibrationMapSaveData
Joystick.GetCalibrationMapSaveData

### Vibration/Rumble

Rewired supports vibration on compatible controllers on certain platforms. See this for more information.

Important: You must have XInput enabled in the Rewired Input Manager on the Windows Standalone platform for Xbox 360 controller vibration support.

Just get the Joystick(s) from the Player class and set the motor levels on each of them.

    // Set vibration by motor type
    foreach(Joystick j in player.controllers.Joysticks) {
        if(!j.supportsVibration) continue;
        j.SetVibration(leftMotorValue, rightMotorValue);
    }

    // Set vibration by motor index
    foreach(Joystick j in player.controllers.Joysticks) {
        if(!j.supportsVibration) continue;
        if(j.vibrationMotorCount > 0) j.SetVibration(0, leftMotorValue);
        if(j.vibrationMotorCount > 1) j.SetVibration(1, rightMotorValue);
    }

    // Set vibration for a certain duration
    foreach(Joystick j in player.controllers.Joysticks) {
        if(!j.supportsVibration) continue;
        if(j.vibrationMotorCount > 0) j.SetVibration(0, leftMotorValue, 1.0f); // 1 second duration
    }

    // Stop vibration
    foreach(Joystick j in player.controllers.Joysticks) {
        j.StopVibration();
    }

This would set vibration on all Joysticks assigned to the Player.

There are also these functions/properties in the Joystick class:
Joystick.supportsVibration
Joystick.vibrationMotorCount
Joystick.GetVibration
Joystick.SetVibration
Joystick.StopVibration
Joystick.vibrationLeftMotor
Joystick.vibrationRightMotor

### Handling button presses of various types

Rewired has a number of methods for handling button presses in a variety of ways.

Most Common:

- Player.GetButton: Gets the button held state of an Action. This will return TRUE as long as the button is held. This also applies to axes being used as buttons.
- Player.GetButtonDown: Gets the button just pressed state of an Action. This will only return TRUE only on the first frame the button is pressed or for the duration of the Button Down Buffer time limit if set in the Input Behavior assigned to this Action. This also applies to axes being used as buttons.
- Player.GetButtonUp: Get the button just released state for an Action. This will only return TRUE for the first frame the button is released. This also applies to axes being used as buttons.

Double Press:

- Player.GetButtonDoublePressHold: Gets the button double pressed and held state of an Action. This will return TRUE after a double press and the button is then held.
- Player.GetButtonDoublePressDown: Gets the button double pressed state of an Action. This will return TRUE only on the first frame of a double press.

Timed Presses:

- Player.GetButtonTimedPress: Gets the button held state of an Action after being held for a period of time. This will return TRUE only after the button has been held for the specified time and will continue to return TRUE until the button is released. This also applies to axes being used as buttons.
- Player.GetButtonTimedPressDown: Gets the button state of an Action after being held for a period of time. This will return TRUE only on the frame in which the button had been held for the specified time. This also applies to axes being used as buttons.
- Player.GetButtonTimedPressUp: Gets the button state of an Action after being held for a period of time and then released. This will return TRUE only on the frame in which the button had been held for at least the specified time and then released. This also applies to axes being used as buttons.
- Player.GetButtonShortPress: Gets the button held state of an Action after being held for a period of time. This will return TRUE only after the button has been held for the specified time and will continue to return TRUE until the button is released. This also applies to axes being used as buttons. The button short press time is set in the Input Behavior assigned to the Action. For a custom duration, use GetButtonTimedPress instead.
- Player.GetButtonShortPressDown: Gets the button state of an Action after being held for a period of time. This will return TRUE only on the frame in which the button had been held for the specified time. This also applies to axes being used as buttons. The button short press time is set in the Input Behavior assigned to the Action. For a custom duration, use GetButtonTimedPressDown instead.
- Player.GetButtonShortPressUp: Gets the button state of an Action after being held for a period of time and then released. This will return TRUE only on the frame in which the button had been held for at least the specified time and then released. This also applies to axes being used as buttons. The button short press time is set in the Input Behavior assigned to the Action. For a custom duration, use GetButtonTimedPressUp instead.
- Player.GetButtonLongPress: Gets the button held state of an Action after being held for a period of time. This will return TRUE only after the button has been held for the specified time and will continue to return TRUE until the button is released. This also applies to axes being used as buttons. The button long press time is set in the Input Behavior assigned to the Action. For a custom duration, use GetButtonTimedPress instead.
- Player.GetButtonLongPressDown: Gets the button state of an Action after being held for a period of time. This will return TRUE only on the frame in which the button had been held for the specified time. This also applies to axes being used as buttons. The button long press time is set in the Input Behavior assigned to the Action. For a custom duration, use GetButtonTimedPressDown instead.
- Player.GetButtonLongPressUp: Gets the button state of an Action after being held for a period of time and then released. This will return TRUE only on the frame in which the button had been held for at least the specified time and then released. This also applies to axes being used as buttons. The button long press time is set in the Input Behavior assigned to the Action. For a custom duration, use GetButtonTimedPressUp instead.

History:

- Player.GetButtonPrev: Gets the button held state of an Action during the previous frame.

Time Information:

- Player.GetButtonTimePressed: Gets the length of time in seconds that a button has been continuously held down. Returns 0 if the button is not currently pressed.
- Player.GetButtonTimeUnpressed: Gets the length of time in seconds that a button has not been pressed. Returns 0 if the button is currently pressed.

Negative Buttons:

Each of the methods above also has a corresponding Negative Button method which is named the same except with NegativeButton in place of Button. These serve to allow you to use axes as buttons and will trigger when the negative side of the axis is activated while the standard Button version will trigger only when the positive side of the axis is activated. However, it is usually easier to just map each pole of the axis to a seperate Action (split axis) so that each Action can just be queried with GetButton.

### Handling multi-button Actions

Rewired does not currently have a way to bind multiple Controller elements to a single Action except for keyboard modifier keys and indirectly through the use of Custom Controllers. To handle button combos, they should be handled in code based on your individual needs (timings, which needs to be pressed first, what cancels what out, etc). In these cases, it can help to think of it as if you're using Actions as buttons:

    // This example shows a simple handling of a 2-button combo where the
    // modifier button must be held down and the primary button pressed

    bool modifier = player.GetButton("ModifierAction"); // get the "held" state of the button
    bool primary = player.GetButtonDown("PrimaryAction"); // get the "just pressed" state of the button

    if(modifier && primary) { // modifier was held or just pressed and primary was just pressed
        // Do something
    }

The constituent Actions can be remapped by the user freely and nothing breaks. You also don't have to worry about the complexities of trying to allow the user to remap actual physical button combos for an Action and worrying about what else may already mapped to the constituent buttons. In addition, this kind of Action combo will work across multiple Controllers and Controller types since Rewired's Player-based input system is largely controller agnostic.

### Excluding certain Players from Joystick auto-assignment

The joystick auto-assignment system has a number of options available, including the option to exclude certain Players from auto-assignment. The "Exclude from Joy Auto Assign" checkbox on the Player in the Rewired Editor allows you to selectively disable joystick auto-assignment for certain Players. Additionally, this can be set in scripting with the player.controllers.excludeFromControllerAssignment property.

Also, the Settings page of the Rewired Editor has a number of options which can be set for Joystick auto-assignment. The "Assign to Playing Players Only" option allows to you exclude Players who are not currently playing or have been disabled by setting the Player.isPlaying property to False.

### Changing configuration settings at runtime

Most configuration settings can be changed at runtime through ReInput.configuration. Please see the ReInput.ConfigHelper API reference for more information.

### Converting scripts from UnityEngine.Input to Rewired

Unity Input Override (the easy way):

Rewired includes the Unity Input Override script to make converting most scripts from Unity input to Rewired effortless and automatic, requiring no code changes to work. It even works with most assets downloaded from the Unity Asset Store. See Unity Input Override for more information.

Modifying script code to use Rewired instead of Unity input (the harder way):

Converting a script from UnityEngine.Input is a very straightforward process for a single player game. For a quick conversion, simply do two find and replace operations:

- "Input.GetButton" -> "Rewired.ReInput.players.GetPlayer(0).GetButton"
- "Input.GetAxis" -> "Rewired.ReInput.players.GetPlayer(0).GetAxis"

This will get the value of each Action from Player 0 for all GetButton, GetButtonDown, GetButtonUp, GetAxis, and GetAxisRaw calls.

You will also need to create the Actions in the Rewired Input Manager that match the string names expected in the code. And of course you will have to create Keyboard, Mouse, Joystick, and/or Custom Controller Maps and assign them to Players as is standard Rewired practice.

If your code has Input.GetKey calls, if you want those to instead use Rewired Actions, you will want to change these to "Rewired.ReInput.players.GetPlayer(0).GetButton" and replace the Unity KeyCode with the name or id of the Action you want to use.

You could also cache the Player object on Awake for the Player in question and use that variable in the find/replace operation, but the above example provides a quick method to convert most scripts that use UnityEngine.Input to Rewired.

### Exporting constants for use in scripting

On the Rewired Input Manager -> Tools page, the section "Export Constants" allows you to export all Actions, Map Categories, and Layouts, to a CS file containing a list of constants. For example, this allows you to use Rewired Actions in scripts without having to type in strings which are prone to typos, plus it allows you take advantage of auto-complete in your IDE. Using constants is also more efficient because integer comparison is faster than string comparison.

Note: The exported constants will only be valid for the Rewired Input Manager from which they were exported. If you have multiple different Rewired Input Managers with different input configurations, you will have to export from both and use a different parent class name for each so they don't conflict. Also, if you add or delete any relevant items in the Rewired Input Manager, the constant list must be exported again.

    // The Action id constants can be used in place of strings throughout the Rewired API

    void Update() {
        Player player = ReInput.players.GetPlayer(0);
        bool fire = player.GetButton(RewiredConsts.Action.Fire) // get the value of "Fire" by using the Action id constant instead of a string
    }

### Displaying a drop-down list of Actions in the inspector of a script

You can display a list of Rewired Actions in a MonoBehaviour script by using the ActionIdPropertyAttribute which will automatically create a Unity property drawer in the inspector.

There are two steps:

1. Export a list of Action id constants from the Rewired Input Manager
2. Create a public integer field in your script and add the ActionIdProperty attribute

Using the ActionIdProperty attribute

In your MonoBehaviour script, create an integer field (or array/list) and add the ActionIdProperty attribute above it. You must pass this attribute a class Type that contains a list of public integer constants. Each constant will be displayed in the drop-down list.

Optional: You can also pass ActionIdProperty an integer Enum type and it will display each item in the enumeration. The drawback of using Enums is that you will have to cast the enum value to an int each time you want to use it in the Rewired API.

    using UnityEngine;
    using Rewired;

    public class MyClass : MonoBehaviour {

        // This attribute denotes this int field as a Rewired Action Id property and will display a drop-down list
        // The class RewiredActions was exported from the Rewired Input Manager and contains a list of Action id constants
        [ActionIdProperty(typeof(RewiredConsts.Action))]
        public int rewiredAction1;

        void Update() {
            Player p = ReInput.players.GetPlayer(0);

            if(rewiredAction1 >= 0) { // make sure the Action id is valid before using it because None = -1
                if(p.GetButton(rewiredAction1)) { // get the button value for the Action
                    Debug.Log("Pressed: " + ReInput.mapping.GetAction(rewiredAction1).name); // log the name of the Action
                }
            }
        }
    }

### Implementing a "Press Start to Join" Joystick assignment system

Normally, Rewired will assign Joysticks to Players when each controller is detected based on settings in the Rewired Input Manager -> Settings page. This will assign a Joystick to each Player in order as they become available so that the first Joystick is assigned to Player 0, the second to Player 1, and so on. But the question has come up many times as to how to be able to let users just pick up any attached controller and press "Start", then have that player join as the next available Player with that Joystick assigned. This kind of assignment method isn't as straightforward to implement.

First you should understand a little bit how Controller Maps work. Controller maps are loaded by the Player, not the Controller, therefore there is no Action named "Start" in the Joystick from which to generate input unless you assign that Joystick to a Player first. Because of this, you cannot simply ask each unassigned Joystick for the value of "Start" to determine if a player wants to join because it doesn't have access to any Controller Maps.

There are various ways this assignment scheme can be achieved. Each method has its own advantages and disadvantages. Please read through them and decide which is most appropriate for your game.

Method 1: Using a variable Rewired.Player as an input source for your own Player object.

1. Make your Players (let's say Player 0 – 3) in the editor.
2. Assign them all Joystick Maps for theJoysticks you want to support.
3. Create a “Start” action and be sure it is assigned in the Joystick Maps you assigned to the Players on some button -- preferably, multiple buttons just to be sure in case a particular Joystick has no Start button (or “Center 2” as defined in the Dual Analog Gamepad Template.) A safe bet would be to put it on “Center 2” and “Action Bottom Row 1” for the Dual Analog Gamepad Template, and Button 0 on Unknown Controller (if you're defining an Unknown Controller Map).
4. Leave Joystick auto-assignment enabled. Rewired will give each Rewired.Player a Joystick if available.
5. Loop through all Rewired.Players and check for player.GetButtonDown(“Start”).
6. Now in your game code, simply assign whichever Rewired.Player returned TRUE to your game-side player object. Your game-side player object may be Player[0], but the Rewired.Player doesn’t have to be. The user could press a button on the Joystick assigned to Rewired.Player[3], but you can still then use Rewired.Player[3] as the input source for your game-side Player[0].

If you also support Keyboard and Mouse, at that point you might want to go ahead and load the appropriate keyboard map Layouts for your Player[0] into Rewired.Player[3]. This works best if keyboard Layouts for the various in-game players will be fixed. IE: Player 1 always uses the WASD set, Player 2 always uses JIKM, etc. (There are ways to make this assignment dynamic too but that's not covered here.)

The following code shows an example of one implmentation of Method 1:

    /* Prerequisites:
     * 1. Create "JoinGame" Action.
     * 2. Create Map Categories "Assignment" and "UI".
     * 3. Create Joystick and Keyboard Maps in the "Assignment" category that map "JoinGame"
     *    to some buttons/keys such as "Start" on in the Dual Analog Gamepad Template and "Space"
     *    and/or "Enter" in the Keyboard Map.
     * 4. Create Joystick and Keyboard Maps in the "UI" category for controlling the UI.
     * 5. Assign the "Assignment" maps to each Player (assign the Keyboard Map to only 1 Player unless you've
     *    created multiple in different layouts for each Player to use). Ensure they are set to be enabled on start.
     * 6. Assign the "UI" maps to each Player setting them to be disabled on start.
     * 7. Leave joystick auto-assignment enabled.
     */
    using UnityEngine;
    using System.Collections.Generic;

    namespace Rewired.Demos {
        using Rewired;

        public class PressStartToJoinPlayerSelector : MonoBehaviour {

            public int maxPlayers = 4;

            private List<PlayerMap> playerMap; // Maps Rewired Player ids to game player ids
            private int gamePlayerIdCounter = 0;

            void Awake() {
                playerMap = new List<PlayerMap>();
            }

            void Update() {

                // Watch for JoinGame action in each Player
                for(int i = 0; i < ReInput.players.playerCount; i++) {
                    if(ReInput.players.GetPlayer(i).GetButtonDown("JoinGame")) {
                        AssignNextPlayer(i);
                    }
                }
            }

            void AssignNextPlayer(int rewiredPlayerId) {
                if(playerMap.Count >= maxPlayers) {
                    Debug.LogError("Max player limit already reached!");
                    return;
                }

                int gamePlayerId = GetNextGamePlayerId();

                // Add the Rewired Player as the next open game player slot
                playerMap.Add(new PlayerMap(rewiredPlayerId, gamePlayerId));

                Player rewiredPlayer = ReInput.players.GetPlayer(rewiredPlayerId);

                // Disable the Assignment map category in Player so no more JoinGame Actions return
                rewiredPlayer.controllers.maps.SetMapsEnabled(false, "Assignment");

                // Enable UI control for this Player now that he has joined
                rewiredPlayer.controllers.maps.SetMapsEnabled(true, "UI");

                Debug.Log("Added Rewired Player id " + rewiredPlayerId + " to game player " + gamePlayerId);
            }

            private int GetNextGamePlayerId() {
                return gamePlayerIdCounter++;
            }

            // This class is used to map the Rewired Player Id to your game player id
            private class PlayerMap {
                public int rewiredPlayerId;
                public int gamePlayerId;

                public PlayerMap(int rewiredPlayerId, int gamePlayerId) {
                    this.rewiredPlayerId = rewiredPlayerId;
                    this.gamePlayerId = gamePlayerId;
                }
            }
        }
    }

Method 2: Easy but does not detect "Start", only any button press:

1. Disable Joystick auto-assignment in the Rewired Editor.
2. In your script, iterate over all Joysticks and check for any button press.
3. Assign that Joystick to the first Player.

Method 3: Detect "Start" button press manually:

1. (Optional) disable Joystick auto-assignment in the Rewired Editor.
2. Assign all Joysticks to the System Player on start so we can detect the result of Actions on Start and whenever one is connected.
3. Check for the value of the "Start" Action you've created and assigned to the Start button or other appropriate button in your Joystick Maps.
4. Get a list of contributing input sources for the "Start" Action and get the target Joystick from InputActionSourceData.controller.
5. Assign that Joystick to Player 1 and deassign it from System.

The following code shows an example implementation of Method 3:

    /* Prerequisites:
     * 1. Create "JoinGame" Action.
     * 2. Create Map Categories "Assignment" and "UI".
     * 3. Create Joystick and Keyboard Maps in the "Assignment" category that map "JoinGame"
     *    to some buttons/keys such as "Start" on in the Dual Analog Gamepad Template and "Space"
     *    and/or "Enter" in the Keyboard Map.
     * 4. Create Joystick and Keyboard Maps in the "UI" category for controlling the UI.
     * 5. Assign the "Assignment" maps to each Player (assign the Keyboard Map to only 1 Player unless you've
     *    created multiple in different layouts for each Player to use). Ensure they are set to be enabled on start.
     * 6. Assign the "UI" maps to each Player setting them to be disabled on start.
     * 7. Leave joystick auto-assignment enabled.
     */
    using UnityEngine;
    using System.Collections.Generic;

    namespace Rewired.Demos {
        using Rewired;

        public class PressStartToJoinPlayerSelector2 : MonoBehaviour {

            public int maxPlayers = 4;
            private int rewiredPlayerIdCounter = 0;

            // Track which Joysticks we've seen before in this session so we can tell new joysticks vs ones that have already been assigned to a Player
            private List<int> assignedJoysticks;

            void Awake() {
                assignedJoysticks = new List<int>();

                // Subscribe to controller connected events
                ReInput.ControllerConnectedEvent += OnControllerConnected;
            }

            void Start() {
                // NOTE: On some platforms/input sources, joysticks are ready at this time, but on others they may not be ready yet.
                // Must also check in OnControllerConected event.

                // Assign all Joysticks to the System Player initially removing assignment from other Players.
                AssignAllJoysticksToSystemPlayer(true);
            }

            void OnControllerConnected(ControllerStatusChangedEventArgs args) {
                if(args.controllerType != ControllerType.Joystick) return;

                // Check if this Joystick has already been assigned. If so, just let Auto-Assign do its job.
                if(assignedJoysticks.Contains(args.controllerId)) return;

                // Joystick hasn't ever been assigned before. Make sure it's assigned to the System Player until it's been explicitly assigned
                ReInput.players.GetSystemPlayer().controllers.AddController<Joystick>(
                    ReInput.controllers.GetJoystick(args.controllerId),
                    true // remove any auto-assignments that might have happened
                );
            }

            void AssignAllJoysticksToSystemPlayer(bool removeFromOtherPlayers) {
                foreach(var j in ReInput.controllers.Joysticks) {
                    ReInput.players.GetSystemPlayer().controllers.AddController(j.id, removeFromOtherPlayers);
                }
            }

            void Update() {

                // Watch for JoinGame action in System Player
                if(ReInput.players.GetSystemPlayer().GetButtonDown("JoinGame")) {
                    AssignNextPlayer();
                }
            }

            void AssignNextPlayer() {
                if(rewiredPlayerIdCounter >= maxPlayers) {
                    Debug.Log("Max player limit already reached!");
                    return;
                }

                // Get the next Rewired Player Id
                int rewiredPlayerId = GetNextGamePlayerId();

                // Get the Rewired Player
                Player rewiredPlayer = ReInput.players.GetPlayer(rewiredPlayerId);

                // Determine which Controller was used to generate the JoinGame Action
                Player systemPlayer = ReInput.players.GetSystemPlayer();
                var inputSources = systemPlayer.GetCurrentInputSources("JoinGame");

                foreach(var source in inputSources) {

                    if(source.controllerType == ControllerType.Keyboard || source.controllerType == ControllerType.Mouse) { // Assigning keyboard/mouse

                        // Assign KB/Mouse to the Player
                        AssignKeyboardAndMouseToPlayer(rewiredPlayer);

                        // Disable KB/Mouse Assignment category in System Player so it doesn't assign through the keyboard/mouse anymore
                        ReInput.players.GetSystemPlayer().controllers.maps.SetMapsEnabled(false, ControllerType.Keyboard, "Assignment");
                        ReInput.players.GetSystemPlayer().controllers.maps.SetMapsEnabled(false, ControllerType.Mouse, "Assignment");
                        break;

                    } else if(source.controllerType == ControllerType.Joystick) { // assigning a joystick

                        // Assign the joystick to the Player. This will also un-assign it from System Player
                        AssignJoystickToPlayer(rewiredPlayer, source.controller as Joystick);
                        break;

                    } else { // Custom Controller
                        throw new System.NotImplementedException();
                    }
                }

                // Enable UI map so Player can start controlling the UI
                rewiredPlayer.controllers.maps.SetMapsEnabled(true, "UI");
            }

            private void AssignKeyboardAndMouseToPlayer(Player player) {
                // Assign mouse to Player
                player.controllers.hasMouse = true;

                // Load the keyboard and mouse maps into the Player
                player.controllers.maps.LoadMap(ControllerType.Keyboard, 0, "UI", "Default", true);
                player.controllers.maps.LoadMap(ControllerType.Keyboard, 0, "Default", "Default", true);
                player.controllers.maps.LoadMap(ControllerType.Mouse, 0, "Default", "Default", true);

                // Exclude this Player from Joystick auto-assignment because it is the KB/Mouse Player now
                player.controllers.excludeFromControllerAutoAssignment = true;

                Debug.Log("Assigned Keyboard/Mouse to Player " + player.name);
            }

            private void AssignJoystickToPlayer(Player player, Joystick joystick) {
                // Assign the joystick to the Player, removing it from System Player
                player.controllers.AddController(joystick, true);

                // Mark this joystick as assigned so we don't give it to the System Player again
                assignedJoysticks.Add(joystick.id);

                Debug.Log("Assigned " + joystick.name + " to Player " + player.name);
            }

            private int GetNextGamePlayerId() {
                return rewiredPlayerIdCounter++;
            }
        }
    }

A quicker but less accurate method would be to do step 1-3 above then:
Loop through each Joystick in the System Player and find out which Joystick was the last to have any button pressed and assign that Joystick to the Player.
This isn't perfect since any button could have been pressed on any Joystick besides the ones assigned to the "Start" action, but in most cases it would probably work fine.
There are also other functions to get the last active Joystick, but they won't help you here because you're only concerned with the "Start" button press and not axes, etc.
Method 4: This method only works if you know your users are going to only be using one specific controller type (such as an Xbox controller on an Xbox system).

1. Use ReInput.controllers.polling.PollAllControllersForAllButtons to poll for button presses.
2. Check the returned ControllerPollingInfo.elementIdentifierId or ControllerPollingInfo.elementIdentifierName to determine which button was pressed.

### Saving and loading Controller Maps

UserDataStore is a class designed to help with saving and loading of Controller Maps, Input Behaviors, calibration settings, and more. Please see User Data Store for more information.

There are several steps involved in saving and loading Controller Maps.

Saving:

1. Get the save data from each Player in XML format.
2. Save the data to a storage medium.

Loading:

1. Identify the Controllers you want to load maps for.
2. Load the map data in XML format.
3. Set the map data in the Player.

Rewired includes a basic system for storing the saved XML data -- UserDataStore_PlayerPrefs which may not be suitable for everyone. Since every game and platform may have different requirements for data storage, you will probably want to write your own data storage system for your specific needs. You will have to save the data in a format most suitable to your game and platform. Possible options are PlayerPrefs, a database, binary or text files, cloud storage, etc. (UserDataStore can optionally be extended to support any storage medium.)

The example mapping demo in Rewired/Examples/ControlRemapping1 includes saving and loading of Controller Maps, Axis Calibration Maps, and Input Behaviors. See this demo project to learn the process of saving and loading. Note: The demo project uses PlayerPrefs for the data storage medium. This is not ideal, but was done for simplicity and cross-platform compatibility for the example. It should not be difficult to substitute another storage medium suitable to your platform.

Example Code from the ControlRemapping1 (see example in Rewired/Examples/ControlRemapping1 for complete code)

    private void SaveAllMaps() {
        // This example uses PlayerPrefs because its convenient, though not efficient, but you could use any data storage method you like.

        IList<Player> allPlayers = ReInput.players.AllPlayers;
        for(int i = 0; i < allPlayers.Count; i++) {
            Player player = allPlayers[i];

            // Get all savable data from player
            PlayerSaveData playerData = player.GetSaveData(true);

            // Save Input Behaviors
            foreach(InputBehavior behavior in playerData.inputBehaviors) {
                string key = GetInputBehaviorPlayerPrefsKey(player, behavior);
                PlayerPrefs.SetString(key, behavior.ToXmlString()); // save the behavior to player prefs in XML format
            }

            // Save controller maps
            foreach(ControllerMapSaveData saveData in playerData.AllControllerMapSaveData) {
                string key = GetControllerMapPlayerPrefsKey(player, saveData);
                PlayerPrefs.SetString(key, saveData.map.ToXmlString()); // save the map to player prefs in XML format
            }
        }

        // Save joystick calibration maps
        foreach(Joystick joystick in ReInput.controllers.Joysticks) {
            JoystickCalibrationMapSaveData saveData = joystick.GetCalibrationMapSaveData();
            string key = GetJoystickCalibrationMapPlayerPrefsKey(saveData);
            PlayerPrefs.SetString(key, saveData.map.ToXmlString()); // save the map to player prefs in XML format
        }

        // Save changes to PlayerPrefs
        PlayerPrefs.Save();
    }

    private void LoadAllMaps() {
        // This example uses PlayerPrefs because its convenient, though not efficient, but you could use any data storage method you like.

        IList<Player> allPlayers = ReInput.players.AllPlayers;
        for(int i = 0; i < allPlayers.Count; i++) {
            Player player = allPlayers[i];

            // Load Input Behaviors - all players have an instance of each input behavior so it can be modified
            IList<InputBehavior> behaviors = ReInput.mapping.GetInputBehaviors(player.id); // get all behaviors from player
            for(int j = 0; j < behaviors.Count; j++) {
                string xml = GetInputBehaviorXml(player, behaviors[j].id); // try to the behavior for this id
                if(xml == null || xml == string.Empty) continue; // no data found for this behavior
                behaviors[j].ImportXmlString(xml); // import the data into the behavior
            }

            // Load the maps first and make sure we have them to load before clearing

            // Load Keyboard Maps
            List<string> keyboardMaps = GetAllControllerMapsXml(player, true, ControllerType.Keyboard, ReInput.controllers.Keyboard);

            // Load Mouse Maps
            List<string> mouseMaps = GetAllControllerMapsXml(player, true, ControllerType.Mouse, ReInput.controllers.Mouse); // load mouse controller maps

            // Load Joystick Maps
            bool foundJoystickMaps = false;
            List<List<string>> joystickMaps = new List<List<string>>();
            foreach(Joystick joystick in player.controllers.Joysticks) {
                List<string> maps = GetAllControllerMapsXml(player, true, ControllerType.Joystick, joystick);
                joystickMaps.Add(maps);
                if(maps.Count > 0) foundJoystickMaps = true;
            }

            // Now add the maps to the controller

            // Keyboard maps
            if(keyboardMaps.Count > 0) player.controllers.maps.ClearMaps(ControllerType.Keyboard, true); // clear only user-assignable maps, but only if we found something to load. Don't _really_ have to clear the maps as adding ones in the same cat/layout will just replace, but let's clear anyway.
            player.controllers.maps.AddMapsFromXml(ControllerType.Keyboard, 0, keyboardMaps); // add the maps to the player

            // Joystick maps
            if(foundJoystickMaps) player.controllers.maps.ClearMaps(ControllerType.Joystick, true); // clear only user-assignable maps, but only if we found something to load. Don't _really_ have to clear the maps as adding ones in the same cat/layout will just replace, but let's clear anyway.
            int count = 0;
            foreach(Joystick joystick in player.controllers.Joysticks) {
                player.controllers.maps.AddMapsFromXml(ControllerType.Joystick, joystick.id, joystickMaps[count]); // add joystick controller maps to player
                count++;
            }

            // Mouse Maps
            if(mouseMaps.Count > 0) player.controllers.maps.ClearMaps(ControllerType.Mouse, true); // clear only user-assignable maps, but only if we found something to load. Don't _really_ have to clear the maps as adding ones in the same cat/layout will just replace, but let's clear anyway.
            player.controllers.maps.AddMapsFromXml(ControllerType.Mouse, 0, mouseMaps); // add the maps to the player
        }

        // Load joystick calibration maps
        foreach(Joystick joystick in ReInput.controllers.Joysticks) {
            joystick.ImportCalibrationMapFromXmlString(GetJoystickCalibrationMapXml(joystick)); // load joystick calibration map if any
        }
    }

Loading the Default Controller Maps:

Default Controller Maps are stored in the Rewired Input Manager. You can load the defaults for a Player by using these methods:

- player.controllers.maps.LoadDefaultMaps - Loads all default Controller Maps from the Rewired Input Manager for all currently-connected devices. Replaces any existing Controller Maps already existing in Player.
- player.controllers.maps.LoadMap - Loads a single Controller Map from the Rewired Input Manager.

Useful API Reference:

Player.GetSaveData - Get all save data from the player at once. This includes Controller Map data.

player.controllers.maps - Methods to get, set, and work with Controller Maps in Player.

### Saving and loading Calibration Maps

UserDataStore is a class designed to help with saving and loading of Controller Maps, Input Behaviors, calibration settings, and more. Please see User Data Store for more information.

The process for saving and loading calibration maps is very similar to Saving and loading Controller Maps, except instead of getting the maps from the Player, you must get the Calibration Map data from the Controllers themselves.

Example Code from the ControlRemapping1 (see example in Rewired/Examples/ControlRemapping1 for complete code)

    private void SaveAllMaps() {
        // ... Removed controller map saving code

        // Save joystick calibration maps
        foreach(Joystick joystick in ReInput.controllers.Joysticks) {
            JoystickCalibrationMapSaveData saveData = joystick.GetCalibrationMapSaveData();
            string key = GetJoystickCalibrationMapPlayerPrefsKey(saveData);
            PlayerPrefs.SetString(key, saveData.map.ToXmlString()); // save the map to player prefs in XML format
        }

        // Save changes to PlayerPrefs
        PlayerPrefs.Save();
    }

    private void LoadAllMaps() {
        // ... Removed controller map loading code

        // Load joystick calibration maps
        foreach(Joystick joystick in ReInput.controllers.Joysticks) {
            joystick.ImportCalibrationMapFromXmlString(GetJoystickCalibrationMapXml(joystick)); // load joystick calibration map if any
        }
    }

Useful API Reference:

player.controllers.maps - Methods to get, set, and work with Controller Maps in Player.

Joystick.calibrationMap - Get the Calibration Map from the Controller.

Joystick.GetCalibrationMapSaveData - Get the Calibration Map save data.

### Modifying Input Behaviors during runtime

Get the Input Behavior you wish to modify from the Player.

ReInput.mapping.GetInputBehaviors - Gets a list of input behaviors from a specific player.
ReInput.mapping.GetInputBehavior - Get a specific Input Behavior from a Player.

Once you have the Input Behavior, modify any property you wish.

API Reference - InputBehavior

You can save Input Behaviors to XML so your runtime changes can be loaded in another game session. The example mapping demo in Rewired/Examples/ControlRemapping1 includes saving and loading of Controller Maps, Axis Calibration Maps, and Input Behaviors. See the example for information on how to save and load Input Behaviors.

### Creating on-screen touch controllers

Touch controllers can be created with the help of Custom Controllers.

Please see the touch controller example in Rewired/Examples/CustomControllers_Touch.

In a future update, ready-made drop-in touch controllers may be included.

### Creating a controller mapping screen

Rewired now includes Control Mapper, a customizable UI control mapping system built with Unity UI that should fit the needs of many games. Please see Control Mapper for more information.

Creating a mapping screen from scratch

Creating a mapping screen can be a difficult task. To get you started, see the example mapping screen in Rewired/Examples/ControlRemapping1. You should be able to adapt this remapping example to fit the needs of your game. The example uses Unity's legacy GUI system.

Every game's needs are different with regards to user mapping screens. The example project was built for a fairly complex game with a number of players and various game modes and supports saving and loading Controller Maps, Joystick assignment, element remapping, calibration, conflict checking, and more. You should be able to learn what you need to from the example project to customize your own mapping screen.

IMPORTANT NOTE:
The ControlRemapping1 demo is 2,000 lines of code. If you are afraid of reading through that much code, stop now and use Control Mapper instead. The vast majority of that code is GUI code to handle all the modal boxes and such. There is a wealth of information in this demo.

Before beginning, it is very important to understand the Controller Map structure and how input is processed in a Player. Please read Controller Maps and also Controller Maps - How Input is Processed in Controller Maps for more information.

Just as a brief summary, the basic process for changing an element's mapping goes like this:

1. Get the Player for which you are changing element mappings.
2. Get the ControllerMap you want to modify from the Player.
   Various functions here can help in finding it. For example:
   player.controllers.maps.GetMap
3. Poll for input from a Controller to determine the element the user wants to bind.
4. Optionally check for element assignment conflicts.
5. Modify an existing ActionElementMap or create a new one with your new assignment. You have your choice of ways to do this, some of which are:
   ControllerMap.ReplaceOrCreateElementMap
   ControllerMap.ReplaceElementMap
   ControllerMap.GetFirstElementMapWithAction (then modify its properties directly)
   ControllerMap.GetElementMapsWithAction
   There are more methods here.

Note that the above summary does not include the extra steps as shown in the demo which cover conflict checking, how to map axes to buttons and vice versa, dealing with split axes, how to poll for input, saving/loading, and a whole lot more. That's all detailed in the demo, so please read through it to learn how it's done.

IMPORTANT NOTE 2:
Creating your own control remapping system is not for beginners and requires patience and a certain level of programming skill. If you do not have the necessary programming skills, patience, or willingness to roll up your sleeves and dig into the code to learn how to do it, you shouldn't attempt it. If your programming skills are at a level where you need a step-by-step tutorial, this topic is too advanced for you. The purpose of this example is to learn the API. If you are looking for a drop-in control remapping system that doesn't require coding, please see Control Mapper.

Question: Can you give me a quick and simple example of how to handle control remapping?

See this answer in the FAQ.

Question: I do not want to read through the code of ControlRemapping1 or Control Mapper because they're too long and complex and I do not like reading other people's code. Give me a simple example.

This link contains a super minimalist joystick remapping example and this link contains a keyboard remapping example. I do not endorse using these examples to learn how to use the Rewired API for controller remapping because they are a gross over-simplification of the process and completely disregard many very important issues with regard to remapping controls, all of which are handled properly and demonstrated in both the ControlRemapping1 demo code and in the Control Mapper code. I strongly suggest you read through the source code in ControlRemapping1 if you want to learn how the remapping API works when used properly.

### Creating new controller definitions

This is an advanced topic. Creating definitions requires a number of tools to help identify the elements and requires thorough testing on several platforms if you desire cross-platform compatibility. To make this process easier, if you have a controller you want to support, please let me know via the support form on the website. I will do my best to get ahold of the controller and add definitions for it. If I cannot, you can arrange to mail the controller to me and I will add definitions for it and then mail it back to you.

A video tutorial is available on YouTube here.

IMPORTANT: Not all controllers are suitable for automatic recognition. Creating definitions for some controllers can cause many problems. Read this first before making a new controller definition.

You can create your own controller definitions if you want to support a specific controller without requiring the user manually map their controller elements. However there are several things you need to be aware of if you want to modify the list of supported controllers:

1. You should copy the ControllerDataFiles object in Rewired/Internal/Data/Controllers to another location (preferably outside the Internal folder) and modify the copy. NEVER modify the original ControllerDataFiles, otherwise when you upgrade Rewired, your ControllerDataFiles will be overwritten and your changes lost.
2. You will need to link your Rewired Input Manager to the new ControllerDataFiles object. Click your Rewired Input Manager in the scene hierarchy and drag-and-drop your copy of ControllerDataFiles into the Data Files field in the inspector. This will instruct Rewired to use your modified ControllerDataFiles instead of the default original.
3. NEVER modify any of the default Hardware Joystick Map or Hardware Joystick Template Map files. If you do, the next time you upgrade Rewired, your changes will be overwritten. Instead, make a copy of any map you wish to modify, move it to another location (preferably outside the Internal folder), also copy the ControllerDataFiles object to another location, then link up the reference to the new Hardware Joystick Map or Hardware Joystick Template map in your ControllerDataFiles object.

Now that you know the rules, here are the steps to creating a new controller:

1. Copy ControllerDataFiles to a new location.
2. Create a new HardwareJoystickMap object from the menu: Window -> Rewired -> Create -> Assets -> Hardware Joystick Map.
3. Move the Hardware Joystick Map to a suitable location.
4. Click your copy of ControllerDataFiles, then in the inspector, modify the Hardware Joystick Maps array to increase its size.
5. Drag and drop your new Hardware Joystick Map into the new element in the array.
6. Now, to edit your new Hardware Joystick Map, click its file and then click "Launch Hardware Joystick Map Editor" in the inspector.
7. Edit the Hardware Joystick Map. The process is as follows:
   - Create Element Identifiers for each of the controller's physical elements. An element can be designated as an Axis or a Button.
   - Select a platform you wish to map such as Raw/Direct Input.
   - On the Matching Criteria tab, fill out the information used to identify the controller. You can get this information by using the tool included for the platform you're editing. See Step 8 below.
   - Create axes and buttons and map them to the platform's input sources. There are various options to help you deal with axes that behave in non-standard ways.
   - Hats should be mapped to buttons, one for each of the four directions.
8. To identify the joystick elements on a particular platform, you may use the tools in the Rewired/DevTools folder. First, you must create a Rewired Input manager in the scene. Then drag the prefab for the appropriate platform prefab from Rewired/DevTools into the scene and press play to see a readout of joystick elements. You may split the game window and edit your hardware map while the game is running so you can see the readout of the elements.
9. Link your new ControllerDataFiles to your Input Manager in the scene so it will recognize the new joysticks.

The Hardware Joystick Map Editor window

### Creating new controller templates

This is an advanced topic. Creating definitions requires a number of tools to help identify the elements and requires thorough testing on several platforms if you desire cross-platform compatibility. To make this process easier, if you have a controller you want to support, please let me know via the support form on the website. I will do my best to get ahold of the controller and add definitions for it. If I cannot, you can arrange to mail the controller to me and I will add definitions for it and then mail it back to you.

See Creating new controller definitions for precautions on working with ControllerDataFiles and Hardware Joystick Maps as the same rules apply here.

1. Create a new HardwareJoystickTemplateMap object from the menu: Window -> Rewired -> Create -> Assets -> Hardware Joystick Template Map.
2. Move the Hardware Joystick Template Map to a suitable location.
3. Click your copy of ControllerDataFiles, then in the inspector, modify the Joystick Templates array to increase its size.
4. Drag and drop your new Hardware Joystick Template Map into the new element in the array.
5. Now, to edit your new Hardware Joystick Template Map, click its file and then click "Launch Hardware Joystick Template Map Editor" in the inspector.
6. Edit the hardware joystick template map by filling out the information. You will need to create a list of Element Identifiers for this template, add joysticks for each joystick the template supports, and create the maps for each joystick.

### Adding a controller to an existing controller template

This is an advanced topic. Creating definitions requires a number of tools to help identify the elements and requires thorough testing on several platforms if you desire cross-platform compatibility. To make this process easier, if you have a controller you want to support, please let me know via the support form on the website. I will do my best to get ahold of the controller and add definitions for it. If I cannot, you can arrange to mail the controller to me and I will add definitions for it and then mail it back to you.

See Creating new controller definitions for precautions on working with ControllerDataFiles and Hardware Joystick Maps as the same rules apply here.

A video tutorial is available on YouTube here.

You can add a new controller definition to an existing template. Be sure the new controller has similar elements and a similar layout. The steps are as follows:

1. First select the Hardware Joystick Map Template object from the Project view.
2. Click the "Launch Hardware Joystick Template Map Editor" button in the inspector.
3. In the window, select the "Joysticks" tab.
4. Add a new joystick which will appear at the bottom of the list.
5. Give this joystick a name. This is only used for identification purposes in this editor.
6. You will need to get the GUID of the joystick you're adding from the Hardware Joystick Map file. Open the Hardware Joystick Map editor for the joystick you're adding, then copythe GUID from the "Settings" tab and paste it in the "Joystick Guid" field of the new joystick in the template editor.
7. You will also need to get the Unity file GUID of the Hardware Joystick Map. This is different from the above GUID. You can obtain this file GUID enabling "Visible Meta Files" in Edit -> Project Settings -> Editor in the application menu, then navigating to the folder with the Hardware Joystick Map and opening the .meta file associated with the asset. The GUID should be clearly visible. Copy this GUID and paste it into the "File Guid" field of your new joystick in the template editor.
8. On the "Maps" tab of the template editor, select your new joystick from the dropdown at the top.
9. Click "Add Entry" to add a new element.
10. You will be mapping each joystick element to a template element. The elements are listed by name.
11. Add as many elements as there are Element Identifiers in your joystick.

### Excluding controller definitions

See Creating new controller definitions for precautions on working with ControllerDataFiles and Hardware Joystick Maps as the same rules apply here.

If there is a particular controller that is included with Rewired that you don't want to support for some reason, you must do the following:

1. Copy ControllerDataFiles to a new location.
2. Click your copy of ControllerDataFiles, then in the inspector, remove the controller you don't want to support from the Hardware Joystick Maps array.
3. Optionally collapse the array to remove any blank spaces.
4. Link your new ControllerDataFiles to your Input Manager in the scene so it will recognize the new joystick list.

### Identifying recognized Joysticks by type

If you need to identify a Joystick for some reason (you're building a controller element glyph table for example), you can determine the identity of a Joystick by using the joystick.hardwareTypeGuid property. This will return the unique GUID of the Joystick type. (Note: This is a Rewired-generated GUID, not from the hardware.) This GUID can be found in each HardwareJoystickMap on the Settings page.

If a Joystick is not a recognized controller, it will always return Guid.Empty (all zeros).

### Identifying controllers on Windows fallback or Windows Webplayer platforms

Update: Unity fixed this issue on Windows in Unity 4.6.3p1 and an early version of Unity 5.x. You can check if the current version of Unity includes the fix by checking the value of ReInput.unityJoystickIdentificationRequired. If true, you should allow your players to manually identify controllers using the methods described below.

Update 2: Windows UWP in Unity fallback mode also has this same issue.

Because of limitations of Unity's input system, you need to take special measures on these platforms for controllers on Windows Standalone (only if you're not using native input -- Raw Input, Direct Input, or XInput -- native input does not have this problem) and Windows Webplayer (native input is not available in Webplayer). Note: This procedure is not required for OSX or other platforms.

Unity's input system has a major problem that makes it impossible to accurately identify which joystick id belongs to which physical controller in Windows. To solve this issue, at game start and at any point a controller is either connected or disconnected, you should ask the user to manually identify each controller one-by-one by pressing a button on the controller that matches the name displayed on-screen.

Rewired provides several functions to facilitate joystick identification:

GetUnityJoystickIdFromAnyButtonOrAxisPress - Returns the 0 based id of the Unity joystick whose button or axis was pressed. -1 if no button or axis was pressed on any joystick. Use this to identify controllers when using Unity's input system. This has no effect if Unity Input is not handling input on the current platform.

GetUnityJoystickIdFromAnyButtonPress - Returns the 0 based id of the Unity joystick whose button was pressed. -1 if no button was pressed on any joystick. Use this to identify controllers when using Unity's input system. This has no effect if Unity Input is not handling input on the current platform.

ReInput.controllers.SetUnityJoystickIdFromAnyButtonOrAxisPress - Sets a Unity joystick as the input source of a Joystick. The first Unity joystick that returns a button or axis press will be assigned to the Joystick. While no buttons or axes are pressed, this will return False. When a press is detected, it will return True and assign the joystick id.

ReInput.controllers.SetUnityJoystickIdFromAnyButtonPress - Sets a Unity joystick as the input source of a Joystick. The first Unity joystick that returns a button press will be assigned to the Joystick. While no buttons are pressed, this will return False. When a button press is detected, it will return True and assign the joystick id.

ReInput.controllers.SetUnityJoystickId - Sets a Unity joystick as the input source of a Joystick. Use this to remap a Joystick to its source when reconnected on platforms that use Unity Input. This has no effect if Unity Input is not handling input on the current platform.

An example is included in Rewired/Examples/FallbackJoystickIdentification which you can look at to see how this is done.

The basic idea is this:

1. At game start, pop up a GUI asking the user to press a button on each named controller.
2. When the user presses the button, set the joystick id on the Joystick so Rewired can identify which physical controller it is.
3. Repeat the above steps for each controller attached to the system.
4. Any time a controller is connected or disconnected, repeat the whole identification process for every controller.

Once the controllers are properly identified, you can use Rewired as usual to receive input, remap controllers, etc. and everything will function properly.

Note: If the user has more than one controller with identical names, there is no way to distinguish between the various controllers for identification. The order that the user identifies the controllers may change Joystick to Player assignments. There is nothing you can do to prevent this. If this happens, the user will have to reassign the Joysticks to players manually using a controller mapping screen. See Creating a controller mapping screen for more information.

FallbackJoystickIdentificationDemo.cs from Rewired/Examples/FallbackJoystickIdentification

    // This example shows how to have the user manually identify joysticks by name to assit with a Unity
    // bug where joysticks cannot be associated with a Unity joystick ID without manual intervention when
    // using Unity as the input source (as opposed to native input).

    // NOTE: This only affects the Windows Standalone and Windows Webplayer platforms and was patched by Unity in 4.6.3p1,
    // so this is no longer required in Unity 4.x versions after 4.6.3p1.
    // This was also fixed in an early version of Unity 5.x, but not in 5.0.

    using UnityEngine;
    using System.Collections.Generic;

    namespace Rewired.Demos {

        [AddComponentMenu("")]
        public class FallbackJoystickIdentificationDemo : MonoBehaviour {

            // Consts
            private const float windowWidth = 250.0f;
            private const float windowHeight = 250.0f;
            private const float inputDelay = 1.0f;

            // Working  vars
            private bool identifyRequired;
            private Queue joysticksToIdentify;
            private float nextInputAllowedTime;
            private GUIStyle style;

            private void Awake() {
                if(!ReInput.unityJoystickIdentificationRequired) return; // this platform does not require manual joystick identificaion

                // Subscribe to device change events
                ReInput.ControllerConnectedEvent += JoystickConnected;
                ReInput.ControllerDisconnectedEvent += JoystickDisconnected; // this event is called after joystick is fully disconnected and removed from lists

                IdentifyAllJoysticks();
            }

            private void JoystickConnected(ControllerStatusChangedEventArgs args) {
                // Identify all joysticks on connect or disconnect because ids are not reliable in Unity
                IdentifyAllJoysticks();
            }

            private void JoystickDisconnected(ControllerStatusChangedEventArgs args) {
                // Identify all joysticks on connect or disconnect because ids are not reliable in Unity
                IdentifyAllJoysticks();
            }

            public void IdentifyAllJoysticks() {
                // Reset each time in case user changes joysticks while dialog is open
                Reset();

                // Check if there are any joysticks
                if(ReInput.controllers.joystickCount == 0) return; // no joysticks, nothing to do

                // Get current Joysticks
                Joystick[] joysticks = ReInput.controllers.GetJoysticks();
                if(joysticks == null) return;

                // Set flag to enable identification mode
                identifyRequired = true;

                // Create a queue out of the joysticks array
                joysticksToIdentify = new Queue(joysticks);

                // Set the time for accepting input again
                SetInputDelay();
            }

            private void SetInputDelay() {
                // Prevent user input for a period of time after each identification to handle button hold problem
                nextInputAllowedTime = Time.time + inputDelay;
            }

            private void OnGUI() {
                if(!identifyRequired) return;
                if(joysticksToIdentify == null || joysticksToIdentify.Count == 0) {
                    Reset();
                    return;
                }

                // Draw dialog window
                Rect centerWindowRect = new Rect(Screen.width * 0.5f - windowWidth * 0.5f, Screen.height * 0.5f - windowHeight * 0.5f, windowWidth, windowHeight); // create a cetered window rect
                GUILayout.Window(0, centerWindowRect, DrawDialogWindow, "Joystick Identification Required"); // draw the window
                GUI.FocusWindow(0); // focus the window

                // Do not allow input during input delay to filter out holding a button down and assigning all joysticks to a single joystick id
                if(Time.time < nextInputAllowedTime) return;

                // Poll for a joystick button press to identify the joystick
                if(!ReInput.controllers.SetUnityJoystickIdFromAnyButtonPress(joysticksToIdentify.Peek().id)) {
                    return; // no input detected
                }

                // Remove the joystick from the queue now that we've used it
                joysticksToIdentify.Dequeue();

                // Renew the input delay time after press
                SetInputDelay();

                // Finish up if the queue is empty
                if(joysticksToIdentify.Count == 0) {
                    Reset(); // done
                }
            }

            private void DrawDialogWindow(int windowId) {
                if(!identifyRequired) return; // window displays 1 frame after it is closed, so this is required to prevent null references below

                // Set up a temporary style with word wrap
                if(style == null) {
                    style = new GUIStyle(GUI.skin.label);
                    style.wordWrap = true;
                }

                // Draw the window contents
                GUILayout.Space(15);
                GUILayout.Label("A joystick has been attached or removed. You will need to identify each joystick by pressing a button on the controller listed below:", style);
                Joystick joystick = joysticksToIdentify.Peek();
                GUILayout.Label("Press any button on \"" + joystick.name + "\" now.", style);

                GUILayout.FlexibleSpace();
                if(GUILayout.Button("Skip")) {
                    joysticksToIdentify.Dequeue();
                    return;
                }
            }

            private void Reset() {
                joysticksToIdentify = null;
                identifyRequired = false;
            }
        }
    }

### Hiding input settings on the Unity launcher

Unity's launcher has a built-in input tab that allows players to customize input through the Unity input manager settings. With Rewired, this interface is not only irrelevant, it is problematic. Rewired sets up over 400 input manager entries to be able to get input from all controllers on Unity fallback platforms. The user should not be allowed to make changes to these default inputs. However Unity gives you no option to hide this input manager settings tab in the launcher. There are three options to deal with this:

1. Disable the launcher. This has the disadvantage of preventing the user from changing the display resolution. To disable it, see Display Resolution Dialog setting in the Unity Player settings.
2. Hack the launcher to hide the input tab. There are no clear guidelines on how to do this, but this forum post shows how one user did it on Windows.
3. Disable the launcher completely and implement your own custom launcher. This allows you to give your user resolution display options as well. (The Unity player can be launched with command line options which set the resolution. See the section Unity Standalone Comand Line Arguments for more information.)

### Optimizing performance

For mobile platforms, squeezing out as much performance as possible is important. Here are some tips to help optimize Rewired's performance in your game:

- If you do not ever get input in FixedUpdate or OnGUI in your game, make sure these Update Loops are disabled in the Rewired Input Manager - Settings page. Each additional update loop you have enabled increases CPU usage of Rewired.
- The more Players, Actions, enabled Controller Maps, and ActionElementMap bindings you have, the more cpu time is required to evaluate input for each of these every update.
- Disable all Controller Maps that are not needed in the current game state. For example, if you have a Map Category for UI controls, disable all UI Controller Maps when the UI is not displayed.
- Use integer contstants instead of string names for calling methods that take an Action, Map Category, or Layout. String comparison is slower than integer comparison. See Exporting constants for use in scripting for information on how to get a list of constants.
- If your game doesn't need keyboard input on certain platforms, disable it using the platform options in the Rewired Editor - Settings page.

Input Events
If you are getting input by using input events, you are shifting the burden of polling for input events on Rewired instead of your scripts which increases its CPU usage. Not only that, but any code in your script that is run in the input event callback will be attributed by the profiler to InputManager_Base instead of your script.

Unity Profiler, Debug Build, and Unity Editor Performance
Unity's profiler in Debug builds tends to report significantly inflated CPU usage for Rewired's InputManager_Base.Update. For example, testing shows that on the PlayStation Vita platform, the profiler will report CPU time up to 2x actual CPU time when timed manually in a Release build. XBox One can report CPU usage of 20x the CPU usage when using a Debug build vs a Development build. In testing on Windows, release builds performed on average 2.5x faster in Unity 4.3 and 3.5x faster in Unity 5.4 than when timed inside the Unity editor. Rest assured, Rewired's core update loop has already been heavily optimized for performance.

Deep Profile
If you enable Deep Profile in the Unity Profiler, InputManager_Base will show a drastically inflated CPU usage due to the fact that Deep Profile uses reflection to get method information. The depth of Rewired's call stack dramatically increases this performance penalty, making it look as if Rewired is taking a huge percentage of the processing time when in reality this is just profiler overhead.

### Using Rewired to control Unity's new UI

See Rewired Standalone Input Module for information.

### Using Apple Siri Remote on Apple TV

In general, the Siri Remote works like any other Joystick in Rewired.

Special mappable elements on the Remote:

- Touchpad X, Y - The X and Y values returned by the remote touchpad. This value is affected by the remote's current relative/absolute setting. This can be changed by setting UnityEngine.Apple.TV.Remote.reportAbsoluteDpadValues.
- Pitch - Returns a -1.0 to +1.0 value based on the current tilt of the remote. Returns 0 when the remote is held with the touchpad end of the remote facing directly up. Positive values correspond to a tilt of the remote toward the screen relative to the 0 position. Negative values correspond to a tilt of the remote away from the screen relative to the 0 position.
- Rotate - Returns a -1.0 to +1.0 value based on the current rotation of the remote. Returns 0 when the remote is held with the touchpad end of the remote facing directly up. Positive values correspond to a clockwise rotation of the remote from the 0 position. Negative values correspond to a counter-clockwise rotation of the remote from the 0 position.
- Acceleration X, Y, Z - Returns the acceleration X, Y, and Z vectors.
- Gravity X, Y, Z - Returns the Gravity X, Y, and Z vectors.

Joystick Assignment
If using Joystick auto-assignment (enabled by default), the Siri Remote is treated as any other Joystick and will be assigned to the first Player found that needs a Joystick assigned based on your current settings. If making a 1-player game, it is highly recommended that you raise the "Max Joysticks Per Player" setting to a large number such as 100 so that all attached Joysticks will be assigned to the Player. This will allow the Player to use the Siri Remote or any gamepad attached without issue.

Please see the Unity Documentation for Apple TV for more information on special considerations for publishing on tvOS.

### Using ArcadeGuns G-500 AimTrak Light Guns

In order for the AimTrak G-500 to work with Rewired, the device must first be configured properly. See Supported Controllers - Configuring ArcadeGuns G-500 AimTrak Light Guns for more information.

The data returned by the AimTrak light guns is not processed by Rewired into a screen-space or world-space coordinate system. The data is returned as it is received from the device. The data must be processed in your scripts in the appropriate manner for your intended use.

The easiest way to tell that the data is from the AimTrak would be to create 2 special Actions specifically for this controller. Something like AimTrakX and AimTrackY. Then in your scripts you can simply check for these Actions and process the values in to the appropriate coordinate system. Alternately, you could check an Action's contributing input sources to determine if that Action was contributed to by the AimTrak by checking the joystick.hardwareTypeGuid property. If the guid is 1708268b-3914-42c4-a339-7bf4fe83fde2, then it is from the AimTrak G-500. (This guid can be found in the HardwareJoystickMap controller definition.)

### Using Sony DualShock 4 special features

The Sony DualShock 4 supports vibration, gyro/accelerometer, touchpad, and changing the light color on Windows Standalone and OSX* only at present (Enhanced Device Support option required.) If you're developing for the PlayStation 4, see Using PS4 gamepad special features on PS4 platform instead. (* Special features are only supported on OSX via wired USB connection.)

The special features of this controller are accessible through the Rewired.ControllerExtensions.DualShock4Extension class.

An example on how to use this class is shown below:

    using Rewired;
    using Rewired.ControllerExtensions;

    class DS4Test {

      // Getting and setting various values on all DS4's assigned to this Player
      public void TestDS4(Player player) {

        // Loop through all Joysticks assigned to this Player
        foreach(Joystick joystick in player.controllers.Joysticks) {

          // Get the Dual Shock 4 Controller Extension from the Joystick
          var ds4 = joystick.GetExtension<Rewired.ControllerExtensions.DualShock4Extension>();
          if(ds4 == null) continue; // this is not a DS4, skip it

          // Get the accelerometer value
          Vector3 accelerometer = ds4.GetAccelerometerValue();

          // Get the gyroscope value
          Vector3 gyro = ds4.GetGyroscopeValue();

          // Get the controller orientation
          Quaternion orientation = ds4.GetOrientation();

          // Get the touch positions for both fingers
          bool touch1isTouching, touch2isTouching;
          Vector2 touch1Pos, touch2Pos;
          touch1isTouching = ds4.GetTouchPosition(0, out touch1Pos);
          touch2isTouching = ds4.GetTouchPosition(1, out touch2Pos);

          // Get/Set vibration
          // Note: Vibration can also be set in a generic way through Joystick.SetVibration
          float vibration = ds4.GetVibration(DualShock4MotorType.WeakMotor);
          ds4.SetVibration(DualShock4MotorType.StrongMotor, 1.0f); // set vibration on a single motor by type
          ds4.SetVibration(1.0f, 1.0f); // set vibration on both motors simultaneously
          ds4.StopVibration(); // stop all vibration

          // Get the light color
          Color lightColor = ds4.GetLightColor();

          // Set the light color
          ds4.SetLightColor(new Color(1.0f, 1.0f, 0.0f, 0.5f)); // alpha is multiplied by rgb to get final value

          // Set the light flash
          ds4.SetLightFlash(1.0f); // flash light every 1 second
          ds4.StopLightFlast(); // stop light flashing

          // Get the battery level
          float battery = ds4.batteryLevel;
        }
      }
    }

### Using P.I. Engineering Rail Driver special features

The P.I. Engineering RailDriver supports all features of the device (Enhanced Device Support option required.)

The special features of this controller are accessible through the Rewired.ControllerExtensions.RailDriverExtension class.

An example on how to use this class is shown below:

    using Rewired;
    using Rewired.ControllerExtensions;

    class RailDriverTest {

      // Getting and setting various values on all RailDrivers assigned to this Player
      public void TestRailDriver(Player player) {

        // Loop through all Joysticks assigned to this Player
        foreach(Joystick joystick in player.controllers.Joysticks) {

          // Get the RailDriver Controller Extension from the Joystick
          var rd = joystick.GetExtension<Rewired.ControllerExtensions.RailDriverExtension>();
          if(rd == null) continue; // this is not a RailDriver, skip it

          // Enable/disable speaker
          rd.speakerEnabled = true;

          // Set LED display
          int ledIndex = 0;
          byte ledDigitByte = 1; // see RailDriver documentation for information on the digit byte
          rd.SetLEDDisplay(0, ledDigitByte);
        }
      }
    }

### Using XBox One controller special features on XBox One platform

Special controller features of the XBox One gamepad such as vibration can be accessed via the XboxOneGamepadExtension class available in the Joystick class as seen in the example below. Note that the platform input source must be set to Native and Disable Native Input must be set to false or no special features will be available.

    using Rewired;
    using Rewired.Platforms.XboxOne;

    class XBoxOneTest {

        void MyMethod() {

            // Set vibration in all controllers in player
            foreach(Joystick joystick in player.controllers.Joysticks) {

                // Get the ControllerExtension for Xbox One and set left gamepad motor to full value
                var extension = joystick.GetExtension<XboxOneGamepadExtension>();

                if(extension != null) { // this is an Xbox One gamepad on the Xbox One platform

                    // Set vibration using the XboxOneGamepadMotorType enum
                    extension.SetVibration(XboxOneGamepadMotorType.LeftMotor, 1.0f);

                } else { // any other controller

                    // Vibration can also be set in a more generic way through
                    // Joystick.SetVibration by using the motor index
                    // This method can also be used to set vibration on the Xbox One Platform
                    joystick.SetVibration(0, 1.0f); // set first motor to full value
                }
            }
        }
    }

### Using PS4 gamepad special features on PS4 platform

Special controller features of the PS4 gamepad such as vibration, gyro, accelerometer, touchpad, and light color can be accessed via the PS4GamepadExtension class available in the Joystick class as seen in the example below. Note that the platform input source must be set to Native and Disable Native Input must be set to false or no special features will be available.

    using Rewired;
    using Rewired.Platforms.PS4;

    class PS4Test {

      // Getting and setting various values on all PS4 gamepads assigned to this Player
      public void TestPS4(Player player) {

        // Loop through all Joysticks assigned to this Player
        foreach(Joystick joystick in player.controllers.Joysticks) {

          // Get the PS4 Gamepad Extension from the Joystick
          var ext = joystick.GetExtension<PS4GamepadExtension>();
          if(ext == null) continue; // this is not a PS4 gamepad, skip it

          // Get the accelerometer value
          Vector3 accelerometer = ext.GetAccelerometerValue();

          // Get the gyroscope value
          Vector3 gyro = ext.GetLastGyroscopeValue();

          // Get the controller orientation
          Quaternion orientation = ext.GetOrientation();

          // Get the touch positions for both fingers
          bool touch1isTouching, touch2isTouching;
          Vector2 touch1Pos, touch2Pos;
          touch1isTouching = ext.GetTouchPosition(0, out touch1Pos);
          touch2isTouching = ext.GetTouchPosition(1, out touch2Pos);

          // Get/Set vibration
          // Note: Vibration can also be set in a generic way through Joystick.SetVibration
          float vibration = ext.GetVibration(PS4GamepadMotorType.WeakMotor);
          ext.SetVibration(PS4GamepadMotorType.StrongMotor, 1.0f); // set vibration on a single motor by type
          ext.SetVibration(1.0f, 1.0f); // set vibration on both motors simultaneously
          ext.StopVibration(); // stop all vibration

          // Set the light color
          ext.SetLightColor(new Color(1.0f, 1.0f, 0.0f, 0.5f)); // alpha is multiplied by rgb to get final value

          // Reset the light color
          ext.ResetLight();
        }
      }
    }

Documentation