Controller Input in Unity for Different OS's

Input in unity is shit.

So, my problem is that I'm working on projects where I use Mac OSX and my partner uses Windows. Thus the bindings for a XBOX360 controller are different.

A - joystick button 0

A - joystick button 16

I'd like to know how you guys deal with an issue like this. I've seen some assets on the asset store but they cost money and they don't explicitly say they handle this issue.

I've thought of just mapping each OS in the InputManager and then using preprocessor directives to choose the string I use in Input.GetAxis(<string chosen>). This seems tedious when it comes to say more than 1 controller.

has an InputManger file that maps 4 controllers but it's for Windows only.

Any suggestions? Asset?



  • edited
    Yeah. This is a fucking pain in the ass.

    For Montez (and my games going forward) we will be using a input mapping system.

    So perhaps you already are doing this but it is generally a good idea to abstract your input into one class. You would have a class named CustomInput and you would have a public static method like Jump() that checks if the jump button is being pressed. This is cool cause you can add multiple jump inputs and stuff like that.

    For example :
    public static bool Jump()
    	if (Input.Getkey(Keycode.Space))
                  return true;
            if (Input.Getkey(Keycode.ArrowUp))
                  return true;
            return false;

    To take this further you can store the keycode in a variable. Which will allow you to change the variable at runtime.
    public static KeyCode myJumpKey = KeyCode.Space;
    public static bool Jump()
    	if (Input.Getkey(myJumpKey))
                  return true;
            return false;

    This isn't necessarily the best solution but so far it has worked.

    For axis you can have a string variable that refers to a InputManager axis. You would have to define every axis you would ever want to use in unitys InputManager and then you can just change that string variable at runtime.
    Thanked by 1SUGBOERIE
  • I've heard some pretty good things about InControl IIRC the open source version isn't in development anymore, but it should be functional and help you with what you need.
    Thanked by 1SUGBOERIE
  • So this is a huge issue with Unity at the moment, and frankly quite ridiculous. I spoke to Lucas about it when he was down here and he was pretty embarrassed about the whole InputManager situation.

    There are actually even more complications than just differing mappings on different platforms. For example:

    - Dual shock controllers have different mappings too (also on a per platform basis), so do MOGAs, and so do most other controller brands.
    - Different controllers treat the triggers differently. Some treat them as buttons, some treat them as separate axes, some treat both triggers as a single axis.
    - Triggers (and possibly other axes) are also treated differently depending on which driver you use. Ever noticed that the standard 360 triggers are a single axis in Unity? ie. holding both is the same as holding nothing at all? Well, the way you solve that is by using XInput instead of DirectInput. Not all controllers support XInput.
    - Vibration is not supported (unless you use XInput, which again, won't work for all controllers).
    - Different controllers treat DPads differently. Some treat them as buttons, some treat them as axes.
    - There is no convenient way to figure what type of controller is attached. All you get is a string name, so you have to do some pattern matching.
    - Joystick IDs don't always align with XInput player ids. You usually have to do some finagling to make sure the controller that is lighting up as player 1 is also player 1 in the game.

    This is a ridiculous amount of stuff to have to care about in order to get gamepads to "just work" in a commercial game engine. Anyway, rant over. What can we do about it? The easiest solution is probably some kind of package, I've also heard good things about InControl.

    I have a custom solution that we use, which evolved from the solution that was used at Tasty Poison Games.

    Basically the idea is to have a standard InputManager.asset file that contains all your InputManager settings ready to be copied into any project. The file should contain axes set up for lots of axes on lots of joysticks. Eg. "Joystick1Axis1", "Joystick1Axis2", "Joystick1Axis3" etc. You probably want at least 8 axes for at least 4 joysticks.

    Then you store mappings for your buttons and axes on a per gamepad and per OS basis. Eg. "XBOX360Windows". You could easily serialize these mappings somewhere, but we just hardcode them into a dictionary in static memory.

    Then finally, you can wrap everything up in a nice static Gamepad class that will check your runtime platform and your controller names and match you with the correct mapping. You can add more complex functionality when you need it. Our gamepad API ends up looking something like this:


  • Thanks guys. :)

    I'm going to check out InControl and see how that works otherwise I may just end up writing a small custom solution similar to the one @squidcor mentioned.
  • I am confused. If you can rebind the inputs then it shouldn't be a problem right ? The player can just rebind the keys to suit him. @squidcor mentioned a lot more problems that I didn't even know existed but if you can rebind the input its irrelevant right ?
  • @Kobusvdwalt9 What are you confused about?
  • Smells like a business opportunity waiting to make some decent money on the unity store ;)
  • I am confused. If you can rebind the inputs then it shouldn't be a problem right ?
    Expecting the player to set up their own bindings in order to use a gamepad is not an ideal solution. Especially when gamepads "just work" with every other game.
    Smells like a business opportunity waiting to make some decent money on the unity store ;)
    Pretty sure InControl is fairly profitable :P

  • @Squidcor Oh ok that makes sense. Technically just having rebindable input works but its not convenient. Well it seems I need to rewrite our thing then.
  • edited
    InControl solves the problem. :D

    It's a really expansive asset. Had PS3 and XBOX360 controllers connected simultaneously and they just worked in harmony.
  • As someone
    @Squidcor Oh ok that makes sense. Technically just having rebindable input works but its not convenient. Well it seems I need to rewrite our thing then.
    No, having rebindable input doesn't work if your controller treats triggers as a bool/int value when your code expects a float for that specific use case. There's only so far you can go by making things user-controlled, you still have to write everything as though it's going to get all the potential different kinds of input that it might get.
    Thanked by 1Kobusvdwalt9
  • This is looks like worthwhile purchase if you're doing lots with controllers:!/content/21676

    When I chimed in about asset store opportunities, it got me thinking about how I would solve this mess - by going to the native level directly. And it seems that exactly what Rewired does - which gives you support for hot swapping a various other features I wasn't able to spot in InControl. ;)
  • @TheFuntastic I remember coming across Rewired a while ago but when I wrote this post I just couldn't remember what it was called. I just assumed it was InControl when that was mentioned. Rewired looks amazing. Thanks for the share.
  • I eventually checked out Rewired. It does have a lot of bells and whistles but It was such a pain to get set up. Felt the same as the stupid Unity input manager.

    So, I just stuck with the free open source InControl and I recently made small teeny weeny changes:

    When the InControlManager component is marked Don't Destroy On Load, it will destroy any other instances of the object when navigating to another scene.

    Due to the controller assignment problem, I also included a Join Screen example to the project.

    The join screen implementation is the one we're using in Raptor Polo and Boxer.
    Thanked by 2Karuji Kobusvdwalt9
  • edited
    Great thread and recommendations. I've personally used cInput but has the same issue as the regular input manager in terms of initial setup. Will look at InControl and Rewired.

    In terms of code, I never write against these libraries directly, always proxy through interface so I can switch out later.
  • One more for ReWired, I've been using that for just about everything and it's quite robust once you get used to its workflow.
  • +1 for Rewired, integrated into a new project recently and it's awesome.
Sign In or Register to comment.