[Free] Custom Input Manager

CONTACT ME
If I don’t answer your message in 1-2 days I probably didn’t get a notification about new replies so email me at daemon3000@hotmail.com

Introduction
InputManager is a custom input manager that allows you to rebind keys at runtime and abstract input devices(through input configurations) for cross platform input.

Features

  • Very simple to implement. It has the same public methods and variables as Unity’s Input class.
  • Allows you to customize key bindings at runtime.
  • Allows you to use XInput for better controller support.
  • Allows you to convert touch input to axes and buttons on mobile devices.
  • Allows you to bind script methods to various input events(e.g. when the user presses a button or key) through the inspector.
  • Run up to four input configurations at the same time for easy local co-op input handling.
  • Save the key bindings to a file, to PlayerPrefs or anywhere else by implementing a simple interface.
  • Seamless transition from keyboard to gamepad with multiple bindings per input action.
  • Standardized gamepad input. Gamepad profiles map various controllers to a standard set of buttons and axes.

Platforms
Works on Windows 7, Windows 8 Desktop, Windows 8 Store, Linux, Mac OSX, WebPlayer and Android(not tested on iOS but it might work).

Download
Visit the github page to get InputManager for free and read detailed instructions.

Getting Started
For detailed information on how to get started with this plugin visit the Wiki or watch the video tutorial linked below.

Code Samples
Key Remap

// Example 1: Changing axis properties
AxisConfiguration axisConfig = InputManager.GetAxisConfiguration("MoveVertical");
axisConfig.positive = KeyCode.W;
axisConfig.negative = KeyCode.S;
axisConfig.sensitivity = 2.0f;
axisConfig.invert = true;
// The AxisConfiguration class allows you to change any parameter that you can change in the custom editor window

// Example 2: Key remap
private void OnGUI()
{
     // Scan for key
     if(GUILayout.Button("Jump"))
    {
        // InputManager.StartKeyScan(KeyScanHandler scanHandler, float timeout, string cancelScanButton, params object[] optional)
        InputManager.StartKeyScan((key, arg) => {
            AxisConfiguration axisConfig = InputManager.GetAxisConfiguration("Jump");
            axisConfig.positive = (key == KeyCode.Backspace) ? KeyCode.None : key;
            return true;
        }, 10.0f, null);
    }
    // Scan for joystick axis
    if(GUILayout.Button("Move"))
    {
        // InputManager.StartJoystickAxisScan(AxisScanHandler scanHandler, int joystick, float  timeout, string cancelScanButton, params object[] optional)
        InputManager.StartJoystickAxisScan((axis, arg) => {
            if(axis >= 0)
            {
                 AxisConfiguration axisConfig = InputManager.GetAxisConfiguration("Move");
                 axisConfig.SetAnalogAxis(0, axis); // Use axisConfig.SetMouseAxis() to change a mouse axis
                 return true;
            }
 
            return false;
        }, 0, 10.0f, null);
    }
}

Save/Load

//    Example 1: Default save and load
InputManager.Save();    //    Saves the configurations in Application.persistentDataPath
InputManager.Load();    //    Loads the configurations from Application.pesistentDataPath

InputManager.Save("MyGame/Profile/input_config.xml");        //    Saves the configurations at a custom path
InputManager.Load("MyGame/Profile/input_config.xml");        //    Loads the configurations from a custom path

//    Example 2: Saving and loading using PlayerPrefs
private void PlayerPrefsSave()
{
    StringBuilder output = new StringBuilder();
    InputSaverXML saver = new InputSaverXML(output);
    InputManager.Save(saver);

    PlayerPerfs.SetString("MyGame.InputConfig", output.ToString());
}

private void PlayerPrefsLoad()
{
    if(PlayerPrefs.HasKey("MyGame.InputConfig"))
    {
        string xml = PlayerPrefs.GetString("MyGame.InputConfig");
        using(TextReader reader = new StringReader(xml))
        {
            InputLoaderXML loader = new InputLoaderXML(reader);
            InputManager.Load(loader);
        }
    }
}
//    Alternatively you can create a custom input saver and loader by implementing IInputSaver and IInputLoader

Create input at runtime

private void CreateKeyboardConfiguration()
{
    InputManager.CreateInputConfiguration("Keyboard");

    //    public static AxisConfiguration CreateDigitalAxis(string configuration, string name, KeyCode positive,
    //                                                      KeyCode negative, float gravity, float sensitivity)
    InputManager.CreateDigitalAxis("Keyboard", "Horizontal", KeyCode.D, KeyCode.A, 3.0f, 3.0f);
    InputManager.CreateDigitalAxis("Keyboard", "Vertical", KeyCode.W, KeyCode.S, 3.0f, 3.0f);
    //    public static AxisConfiguration CreateButton(string configuration, string name, KeyCode key)
    InputManager.CreateButton("Keyboard", "Jump", KeyCode.Space);

    InputManager.SetConfiguration("Keyboard");
}

private void CreateJoystickConfiguration()
{
    InputManager.CreateInputConfiguration("Joystick");

    //    public static AxisConfiguration CreateAnalogAxis(string configuration, string name, int joystick, int axis,
    //                                                     float sensitivity, float deadZone)
    InputManager.CreateAnalogAxis("Joystick", "Horizontal", 0, 0, 1.0f, 0.1f);
    InputManager.CreateAnalogAxis("Joystick", "Vertical", 0, 1, 1.0f, 0.1f);
    InputManager.CreateButton("Joystick", "Jump", KeyCode.JoystickButton0);

    InputManager.SetConfiguration("Joystick");
}
//    Note: "CreateButton" and "CreateDigitalAxis" have overloads that take secondary keys

License
This software is released under the MIT license.

3 Likes

The webplayer shows a white rectangle.

Fixed the link. Try again here.

The web demo is actually the example scene for the project. If it doesn’t work just download the project and test it there.

Wow, thanks for this. I downloaded it and it works great. I was just thinking about my own solution, but I’ll just use this instead. I’m not a fan of the unity input system so this is a godsend.

I also appreciate the open source so I can change it and modify it for my projects. If I make any thing worthy I’ll hand it to you on this thread.

Thanks again.

A new update for InputManager is available.

Changes:

  • Fixed a bug where you couldn’t change mouse and joystick axis at runtime
  • InputAdapter addon that manages keyboard and XBox 360 Controller input with seamless transition from one to the other. Test it in the new demo here
  • New example scene to show you how to set up and use the InputAdapter addon

That’s great!

Can we make this compatible with the OUYA controller? I’m not sure how though. I can take a look at it later.

If you want to make the InputAdapter addon work with a OUYA controller instead of a Xbox controller you might need to make some changes to the script. The current version of the InputAdaper expects two configurations for the controller because of the differences between the OSX and Windows drivers. If the OUYA controller has the same mapping on both platforms you’ll need to edit the InputAdapter script so it expects only one configuration for the controller else you can use it as it is, no changes required.

To get the OUYA controller mapping for Unity download the helper script from here. You’ll need the custom “InputManager.asset” file from the InputManager project.
Run a test scene with the helper script and press the buttons and the analog sticks one by one to see the KeyCode values and the axis numbers.

So I’ve been trying to figure out how to setup where it can read the mouse x and y movement. Can you help?

Here is the error message:

Edit: Nevermind. I hadn’t imported the asset file into my project settings folder yet.

I’m glad you could fix it. With the new update you’ll get a dialog when you import InputManager that lets you know you need to replace the file.

One big improvement to this would be to have the editor render everything inside the Inpector, rather than a new editor window. It would make changes easier that way.

New updates for InputManager are available.
Changes from 1.2:

  • Undo support for the inspector and the advanced editor
  • Input configurations can now be edited in the inspector
  • Fixed some bugs related to the editor GUI for Unity 4.3

Changes from 1.1:

  • The Advanced Editor is now able to edit prefabs
  • You now get a warning that lets you know you need to overwrite the input settings
  • Various tweaks and fixes

Good stuff man! I’ll look at adding joystick calibration and the move from the dark side will be complete :slight_smile:

Great changes. Working much better having the inspector.

Thanks for the support and feedback.

A new update for InputManager is available.

Changes from 1.3:

  • Support for creating and deleting axes at runtime. See code samples in the original post and read the readme file(API category) for more info

I love this! Not sure if this is a bug, but when I use the joystick on the right on the Dualshock 3, it returns very strange values, such as when I push it upwards, the camera in game rotates diagonal. Thanks so much for making this open source AND free!

Unfortunately I don’t have a Dualshock 3 so I can’t test it. Maybe you used wrong values for the sensitivity or dead zone or maybe you have two axis configurations that use the same joystick axis. Create a new project and see what values it returns when using the built-in Input class then compare them with what you get now. Maybe that will give you an idea on how to fix it or maybe there’s something wrong with the joystick. Let me know how it turns out so I can patch it if it’s a bug.

Hi there. Firstly I really appreciate you giving me, an “out of work hobbyist”, an opportunity to use your code for free but I’m trying to get your code working and I think I’m missing something obvious.

I’m using VS2013 C# and I’m simply trying to implement your StartJoystickAxisScan which I have as follows…

    void OnGUI() {
        if(GUILayout.Button("Move")) {
            InputManager.StartJoystickAxisScan((axis, params object[] arg) => {
                if(axis >= 0) {
                    AxisConfiguration axisConfig = InputManager.GetAxisConfiguration("Move");
                    axisConfig.SetAnalogAxis(0, axis);
                }
            }, 0, 10.0f, null);
        }
    }

Unfortunately, I just get an error tool tip over InputManager.StartJoystickAxisScan (and can’t compile) stating

(parameter) int axis

Error:
No overload for method ‘StartJoystickAxisScan’ takes 1 arguments

Please try and point me in the right direction as I’ve been trying to get my input mapping sorted for over a week now using various methods, and yours looks like the easiest (if I can get it working that is). I hope I’m not being a dumb dumb and have missed something real simple.

That example is out of date and has some errors. Use this one instead:

void OnGUI()
{
    if(GUILayout.Button("Move"))
    {
       InputManager.StartJoystickAxisScan((axis, arg) => {
                if(axis >= 0)
                {
                    AxisConfiguration axisConfig = InputManager.GetAxisConfiguration("Move");
                    axisConfig.SetAnalogAxis(0, axis);
                    return true;
                }

                return false;
        }, 0, 10.0f, null);
    }
}

Let me know if you have other problems and thank you for pointing this out to me.

Thanks very much! That was driving me nuts, but glad to see it wasn’t me ;). You may wish to update your WIKI too as that has the same erroneous example.

Hi! First of all, thanks so much for this!

I’ve tried the example project and it works fine, but I’m having some trouble importing this into my own project. I imported it into the root Assets folder and got a ton of errors saying it didn’t know what the InputManager class was (when referencing from my script):
Assets/Scripts/PlayerControl.cs(70,38): error CS0103: The name `InputManager’ does not exist in the current context

I’m using Unity 4.5.0

Help?

EDIT:
Solved by adding “using TeamUtility.IO;”
That should probably be in the instructions on the ReadMe… :slight_smile: