Search Unity

InControl - input and cross platform controller support for Unity, made easy!

Discussion in 'Assets and Asset Store' started by pbhogan, Jul 18, 2014.

  1. pbhogan

    pbhogan

    Joined:
    Aug 17, 2012
    Posts:
    384
    Hi folks—I just noticed a bunch of questions on this thread which, frustratingly, aren't being e-mailed to me by Unity despite me having enabled "watching" the thread. So I'll just mention it's generally best to e-mail me if you want immediate (usually same-day) support. :) My e-mail is contact at gallantgames.com

    @djfrail Yes, I'm afraid there is nothing I can do about that. I need to call Input.GetJoystickNames() every so often to detect joystick connects / disconnects, so I try to do it only every second or so, instead of every frame.

    @Mistale Please e-mail me the particulars of your problem—it sounds like you're trying to use touch controls with an OUYA controller or... something? Let me know your platform and setup, in particular, so I can try to replicate it.

    @ottolb There isn't a way to do this. All InputDevices should be joysticks unless you have a virtual device created by a custom profile, in which case you can just check for the device name and anything else will be a joystick. Also, the new bindings API should basically make it unnecessary to use custom profiles. Feel free to e-mail me for any clarification you need.
     
  2. loko08

    loko08

    Joined:
    Oct 6, 2013
    Posts:
    57
    Hello Patrick!

    First of all, thank you I am in love with InControl (all of my team is). But we are having a very weird bug and we have no idea what's going on.

    We have a "load all" scene, where the inControl Manager is created and from there on, all controls in the game work fine. But for testing, this isn't ideal, since we need to test each scene first.

    We were using an object on each scene that we could enable to allow us to move around. But now, even if the object is active, the Input is never read, and when I was debugging the code, the name of the device said "None" even though we are using the Keyboard and Mouse Custom Profile (and it works fine IF we load the game from the starting "loadAll" scene).

    I have already tried to move around the Script Execution order, but it seems like this isn't working either.

    Any help is greatly appreciated.
    JP
     
  3. pbhogan

    pbhogan

    Joined:
    Aug 17, 2012
    Posts:
    384
    @loko08 Could you e-mail me a stripped down example showing the problem? I know many folks are doing things this way and it works, so it's probably something in the setup. Specifically, I'm unsure of what you mean by an object that you enable to allow you to move around. My e-mail is contact at gallantgames.com
     
  4. UnbreakableOne

    UnbreakableOne

    Joined:
    Nov 16, 2013
    Posts:
    168
    I have an attached wired xbox 360 controller that works with Steam games on my Mac OS X 10.10 but can't get it to work in InControl. Tried your Introduction video step by step, but debug log doesn't say that it found anything and when I debug, the ActiveDevice is null.

    Thanks.
     
  5. pbhogan

    pbhogan

    Joined:
    Aug 17, 2012
    Posts:
    384
    @UnbreakableOne You're using Unity 5? There is currently a bug with Unity 5 on OS X where it won't recognize controllers until after restart. Some people say it never does for them, although I have not had this happen (my primary dev platform is OS X 10.10). Unity is aware and I've been told a fix is coming soon.

    You'll also need to be using this driver for Yosemite if you're not already doing so, although it sounds like you are:
    https://github.com/d235j/360Controller/releases
     
  6. UnbreakableOne

    UnbreakableOne

    Joined:
    Nov 16, 2013
    Posts:
    168
    Thanks. Problems solved partially as it happens randomly and I have to restart again. Am using 5.0.0f4 on Yosemite.

    Another question, I'm prototyping a local multiplayer game with controllers (one PS3 controller via Bluetooth and one wired Xbox 360). What's the "correct" way to read input of those devices and apply them to different entities?
     
  7. pbhogan

    pbhogan

    Joined:
    Aug 17, 2012
    Posts:
    384
  8. UnbreakableOne

    UnbreakableOne

    Joined:
    Nov 16, 2013
    Posts:
    168
    Trying to add multiplayer to my game. I've had success with PlayerActions and not binding a button to a game logic activity, and I love it.

    Then I opened the included Multiplayer demo and I noticed you are checking specific buttons to do game logic.

    My question is, is there anyway to assign game logic to player actions for each player? For simplicity we can assume that each player has a "playerNum", like your example.

    Thanks
     
  9. pbhogan

    pbhogan

    Joined:
    Aug 17, 2012
    Posts:
    384
    @UnbreakableOne That example really needs to get updated. It's not a good example of how to do anything anymore because using an index into the devices list is totally wrong, and it doesn't use the bindings system.

    But anyway, the answer to your question is to set the Device property on your PlayerActionSet subclass instance to the specific device you want to query. When that property is set to null, it queries InputManager.ActiveDevice instead. So you'd have an instance for every player each with a different device assigned for controllers (or if it has only keyboard bindings it doesn't need any device assigned).
     
  10. UnbreakableOne

    UnbreakableOne

    Joined:
    Nov 16, 2013
    Posts:
    168
    How can I do this correctly? (Any example code perhaps?)

    I see that I can assing a Device into Device property of PlayerActionSet but as you've described in the documentation (and also again in this topic), it's not easy and straightforward to do.

    What I mean is, when game starts, I know that one GameObject is Player1 and another is Player 2 and we know that it's not a good thing thing to assign Device[0] and Device[1] to them. What should I do?

    Thanks!
     
  11. pbhogan

    pbhogan

    Joined:
    Aug 17, 2012
    Posts:
    384
    @UnbreakableOne I don't have example code, but it is by no means hard. Just listen for an input press on all devices (with InputManger.ActiveDevice) and when you detect a press add a player and assign the device that was pressed. Either you can listen for a specific control, or set up an action set just for the purpose of this listening (which by default will listen to all devices). When you detect a press, create a new action set instance and set the device to the value of InputManager.ActiveDevice which by definition is the device that last provided input.

    If you have keyboard players in the mix it will require a little more logic to make sure only one keyboard player is added, etc. Either have a separate action set for that, or you can have both on the same input set and determine if what input source type was used with the PlayerActionSet.LastInputType property (http://www.gallantgames.com/incontrol-api/html/class_in_control_1_1_player_action_set.html).
     
  12. UnbreakableOne

    UnbreakableOne

    Joined:
    Nov 16, 2013
    Posts:
    168
    Thanks.

    What I've done so far is to create a MultiplayerInputManager that listens to OnActiveDeviceChanged and tries to respond accordingly. Here it is:

    Code (csharp):
    1.  
    2.   intnumOfPlayers, currentPlayer;
    3.  
    4.  
    5. voidStart ()
    6.  {
    7. numOfPlayers = LevelManager.Instance.DebugSpawns.Length;
    8. InputManager.OnActiveDeviceChanged += HandleOnActiveDeviceChanged;
    9.  }
    10.  
    11. voidHandleOnActiveDeviceChanged (InputDeviceobj)
    12.  {
    13. Debug.Log(obj.Name);
    14. LevelManager.Instance.Players[currentPlayer++].GetComponent<CorgiInputManager>().PlayerActions.Device = obj;
    15.  
    16. currentPlayer = currentPlayer == numOfPlayers ? 0 : currentPlayer;
    17.  }
    18.  
    And then have a code on each player that handles input based on the PlayerActions.

    (Since I'm having problem setting up everything, I'm omitting the device detachment issue for now)

    1) I want to assign each player to a controller at the start of the game but

    2) Should each player has a instance on InputManager on it or there should be a singleton that checks for inputs and updates players with the input?

    3) Would you please post updated version of the multiplayer example code?
     
  13. pbhogan

    pbhogan

    Joined:
    Aug 17, 2012
    Posts:
    384
    @UnbreakableOne You can't really use OnActiveDeviceChanged for this or you'll keep creating new players with devices already previously assigned. And I think you'll need some kind of user interface / menu for assigning new players. The basic process is (and this is just one way of handling it):
    Create an instance of your player action set.
    Wait for a press.
    When a press happens, look at all existing players to see if InputManager.ActiveDevice is already used.
    If not, create a new player with a new action set instance assigning that device to it.
    Otherwise keep listening until the game starts.
    Where you store the action sets or devices is up to you, but I'd imagine you'd have some kind of singleton around you can put them on.

    I'll post a new example in a future update.
     
  14. Cronos05

    Cronos05

    Joined:
    Sep 26, 2012
    Posts:
    12
    Hi there! Thanks for the excellent package. It is amazing, specially the new bindings system.

    I have a doubt and maybe someone can help me: in my bindings I created a OneAxisPlayerAction for steering between left and right. Before InControl I was simply using Input.GetAxis("Horizontal") and its sensitivity used to gradually change its value between 0 and 1, even when using keyboard keys. With InControl I'm using the value from a PlayerOneAxisAction for my steering and it's always returning 0 and 1, raw through keyboard.

    I tried deactivating it's "raw" property within OneAxisPlayerAction to have its value gradually changed over time, but sensitivity is set high and it doesn't seem I can change it without hardcoding that value in InControl code.

    Is this gradual change in an input axis using keyboard something achievable through InControl? If so, what am I missing to achieve it?

    Thanks!
     
    Last edited: May 19, 2015
  15. pbhogan

    pbhogan

    Joined:
    Aug 17, 2012
    Posts:
    384
    @Cronos05 Yes, InControl doesn't do any smoothing on inputs so it'll just give you the instant value on any control, whatever it may be. For buttons and keyboard controls it's going to be 0 and 1. Applying smoothing yourself is pretty simple using something like Mathf.MoveTowards() or maybe Mathf.SmoothDamp()
     
    Cronos05 likes this.
  16. Cronos05

    Cronos05

    Joined:
    Sep 26, 2012
    Posts:
    12
    Alright, thanks for the feedback @pbhogan! I'll do the smoothing separated like you suggested. :)
     
  17. UnbreakableOne

    UnbreakableOne

    Joined:
    Nov 16, 2013
    Posts:
    168
    Thanks for the reply. I'm doing prototyping and don't need an elegant solution like separate window to do so. So how can I get the two active devices and store their references and assign them to each player?
     
  18. yoDon

    yoDon

    Joined:
    Aug 29, 2008
    Posts:
    44
  19. RChrispy

    RChrispy

    Joined:
    Dec 18, 2013
    Posts:
    71
    Hey :) I have a question. :p
    I try to make some multiplayer controls for my game and use the defaultkeybinding atm.
    I created some assets to control my input per player just wanted to try it out. More than one binding per action like W and Space for jumping. ;) [My binding debug logs are running through normaly]
    Those are the 3 scripts:

    It worked but now it doesn't. Did I something wrong here? Please help :D
     

    Attached Files:

    Last edited: May 25, 2015
  20. RChrispy

    RChrispy

    Joined:
    Dec 18, 2013
    Posts:
    71
    Oh damn i am so stupid XD forgott to activate the InControlManager script again!
    But well maybe you like the idea of using assets dnk what you think about it? Didn't see a tutorial using InControl that way. ^^
     
  21. pbhogan

    pbhogan

    Joined:
    Aug 17, 2012
    Posts:
    384
    No, it's currently not possible to do. The Xbox One controller does not work wirelessly with PCs (or Macs). It only works over USB cable: http://support.xbox.com/en-US/xbox-one/accessories/controller-pc-compatibility
     
  22. pbhogan

    pbhogan

    Joined:
    Aug 17, 2012
    Posts:
    384
    The active device (InputManager.ActiveDevice) is the one that last provided input. Normally you would get references by listening for a press and then saving that device, something like:
    var device = InputManager.ActiveDevice;
    if (device.Action1.WasPressed && DeviceNotAlreadyAssignedToPlayer( device ))
    {
    CreatePlayerWithDevice( device );
    }

    If you're just prototyping you may be able to get away with InputManager.Devices[0] and InputManager.Devices[1] for a while if you're sure only the two controllers are attached, but you should never release a game that does things this way as it won't always work.
     
  23. pbhogan

    pbhogan

    Joined:
    Aug 17, 2012
    Posts:
    384
    A better example of doing multiplayer with bindings is coming in the next update, which might be more like what you're doing here. :)
     
  24. RChrispy

    RChrispy

    Joined:
    Dec 18, 2013
    Posts:
    71
    InControl is awesome! Its so easy to modify! Keep up the good work. ;)
     
  25. ottolb

    ottolb

    Joined:
    Jul 1, 2009
    Posts:
    42
    Hi guys!
    I'm currently developing a game using the InControl. And I'm having a strange problem. My partner have a Wacom tablet, plugged on usb, and we discovered that this device prevents joysticks of being recognising in Unity!
    If I turn off the Wacom the joysticks work properly.
    Anyone having similar issues?

    BTW if you want test the game (BETA) here is the link: goo.gl/ydZnml
    Thanks
     
  26. pbhogan

    pbhogan

    Joined:
    Aug 17, 2012
    Posts:
    384
    Can't say I've ever heard of this particular problem, but if you can verify it happens with a stock Unity app you should definitely report it to Unity.
     
  27. TechiTech

    TechiTech

    Joined:
    Dec 13, 2014
    Posts:
    212
    "As of version 1.3.0, InControl includes an InControlInputModule component which you can add to the EventSystem game object. It is intended to replace the default StandaloneInputModulecomponent to feed input events directly from InControl to the new Unity GUI added in Unity 4.6."

    so where is "InControlInputModule" I can't find it anywhere in my project... component not there no script?

    EDIT :

    Found it but when I try to add it I get an error. Is it compatible with Unity 5?
     

    Attached Files:

    Last edited: Jun 1, 2015
  28. pbhogan

    pbhogan

    Joined:
    Aug 17, 2012
    Posts:
    384
    Yes, it is compatible with Unity 5. However, it is wrapped with a preprocessor: #if UNITY_4_6 || UNITY_5_0
    Are you possibly running an alpha or beta version beyond the 5.0 range? If so, you'll need to modify the preprocessor guard.
     
  29. TechiTech

    TechiTech

    Joined:
    Dec 13, 2014
    Posts:
    212
    yep I'm running 5.1

    ok sorted.. thanks
     
    Last edited: Jun 1, 2015
  30. coolblue2000

    coolblue2000

    Joined:
    May 7, 2015
    Posts:
    24
    I have a warning on my menu scene about multi event systems. I assume it is to do with unity ui conflicting with incontrol. How do I integrate them both? I am using unity 5.02
     
  31. pbhogan

    pbhogan

    Joined:
    Aug 17, 2012
    Posts:
    384
    There shouldn't be a conflict. InControl has its own InControlInputModule component you can use instead of StandardInputModule. You shouldn't use both at the same time. Beyond that you'll need to e-mail me specifics about the warning you're getting.
     
  32. username132323232

    username132323232

    Joined:
    Dec 9, 2014
    Posts:
    477
    I'm just getting started with InControl and have a basic question. Is it possible to map InputControlType.Action1 into InputControlType.Action2 so that the game would see them as the same button?

    Also, what is the purpose of Handle in InputControlMapping?

    Thanks!
     
    Last edited: Jun 11, 2015
  33. col000r

    col000r

    Joined:
    Mar 27, 2008
    Posts:
    699
    I'm trying to map the mousewheel to lefttrigger/righttrigger like this in a custom profile:

    Code (CSharp):
    1.                 new InputControlMapping {
    2.                     Handle = "Zoom In",
    3.                     Target = InputControlType.RightTrigger,
    4.                     Source = MouseScrollWheel,
    5.                     SourceRange = InputRange.ZeroToMinusOne,
    6.                     TargetRange = InputRange.ZeroToOne,
    7.                     Raw = true,
    8.                     Scale = 1f
    9.                 },
    10.                 new InputControlMapping {
    11.                     Handle = "Zoom Out",
    12.                     Target = InputControlType.LeftTrigger,
    13.                     Source = MouseScrollWheel,
    14.                     SourceRange = InputRange.ZeroToOne,
    15.                     TargetRange = InputRange.ZeroToOne,
    16.                     Raw = true,
    17.                     Scale = 1f
    18.                 }
    But it doesn't work - no matter which direction I scroll, it only zooms one way (works perfectly in both directions if I actually use the Triggers on the controller)

    What am I doing wrong?
     
  34. pbhogan

    pbhogan

    Joined:
    Aug 17, 2012
    Posts:
    384
    No. You need to either read from both controls, or if you're using the bindings API you can add both controls as bindings to the same action.

    Handle is basically a string name for the control, specific to the device in question. Usually I try to match it to whatever terminology the manufacturer uses to describe the control, or the label on the device.
     
    username132323232 likes this.
  35. pbhogan

    pbhogan

    Joined:
    Aug 17, 2012
    Posts:
    384
    Could be a bug... I'll investigate.

    You should probably transition to using the new bindings API for this though. Custom profiles are going to be deprecated soon.
     
  36. username132323232

    username132323232

    Joined:
    Dec 9, 2014
    Posts:
    477
    Thank you! Binding was exactly what I needed.
     
  37. username132323232

    username132323232

    Joined:
    Dec 9, 2014
    Posts:
    477
    Is it possible to add some kind of event listener to a PlayerActions object? I would like to avoid checking if the control was pressed in the Update() or a similar function.

    Sorry for another basic question, but I wasn't able to find this info in the documentation. If it's there, please give me the link. Thanks again.
     
  38. username132323232

    username132323232

    Joined:
    Dec 9, 2014
    Posts:
    477
    I tried using InControl with Amazon Fire TV remote and game controller. InputControlType.Menu works for the Menu button, but InputControlType.Back doesn't seem to work with the Back button. Any suggestions? Thanks.
     
  39. StefanoCecere

    StefanoCecere

    Joined:
    Jun 10, 2011
    Posts:
    211
    Hi patrick

    pay attention that #if UNITY_4_6 || UNITY_5_0 isn't true with Unity 5.1
     
  40. rsodre

    rsodre

    Joined:
    May 9, 2012
    Posts:
    229
    Hello!
    First, congratulations for this awesome plugin, I've been waiting for this a long time!

    I'm using a custom Mouse Profile and there's something bothering me.
    On my game, the mouse is used for camera view. It works fine, but when I stop moving the mouse, it starts to climb back to default zero value. I don't want this, I want to precisely place my camera and just go back when I want, moving the mouse.
    How do I stop the mouse value to go back to zero?

    Here's my mouse mapping sample:

    Code (CSharp):
    1.         AnalogMappings = new[] {
    2.             new InputControlMapping {
    3.                 Handle = "Look Up",
    4.                 Target = InputControlType.RightStickUp,
    5.                 Source = MouseYAxis,
    6.                 SourceRange = InputRange.ZeroToPositiveInfinity,
    7.                 TargetRange = InputRange.ZeroToOne,
    8.                 Raw = true,
    9.                 Scale = 0.01f
    10.             },
    11.             new InputControlMapping {
    12.                 Handle = "Look Down",
    13.                 Target = InputControlType.RightStickDown,
    14.                 Source = MouseYAxis,
    15.                 SourceRange = InputRange.ZeroToNegativeInfinity,
    16.                 TargetRange = InputRange.ZeroToMinusOne,
    17.                 Raw = true,
    18.                 Scale = 0.01f,
    19.                 Invert = true
    20.             },
    21.             new InputControlMapping {
    22.                 Handle = "Look Left",
    23.                 Target = InputControlType.RightStickLeft,
    24.                 Source = MouseXAxis,
    25.                 SourceRange = InputRange.ZeroToNegativeInfinity,
    26.                 TargetRange = InputRange.ZeroToMinusOne,
    27.                 Raw = true,
    28.                 Scale = 0.01f,
    29.                 Invert = true
    30.             },
    31.             new InputControlMapping {
    32.                 Handle = "Look Right",
    33.                 Target = InputControlType.RightStickRight,
    34.                 Source = MouseXAxis,
    35.                 SourceRange = InputRange.ZeroToPositiveInfinity,
    36.                 TargetRange = InputRange.ZeroToOne,
    37.                 Raw = true,
    38.                 Scale = 0.01f
    39.             },
    40.             new InputControlMapping {
    41.                 Handle = "Look Z",
    42.                 Target = InputControlType.LeftTrigger,
    43.                 Source = MouseScrollWheel,
    44.                 SourceRange = InputRange.ZeroToNegativeInfinity,
    45.                 TargetRange = InputRange.ZeroToMinusOne,
    46.                 Raw = true,
    47.                 Scale = 0.1f,
    48.                 Invert = true
    49.             },
    50.             new InputControlMapping {
    51.                 Handle = "Look Z",
    52.                 Target = InputControlType.RightTrigger,
    53.                 Source = MouseScrollWheel,
    54.                 SourceRange = InputRange.ZeroToPositiveInfinity,
    55.                 TargetRange = InputRange.ZeroToOne,
    56.                 Raw = true,
    57.                 Scale = 0.1f
    58.             },
    59.         };
    60.  
     
  41. rsodre

    rsodre

    Joined:
    May 9, 2012
    Posts:
    229
    Also, directions for integration with new UI close to zero, and there's no example.
    Is there any specific place to put the Input Module?
    StandaloneInputModule? what/where is it? how to replace it?
     
  42. pbhogan

    pbhogan

    Joined:
    Aug 17, 2012
    Posts:
    384
    No, there is currently no event handling in InControl. I might add them in the future.
     
  43. pbhogan

    pbhogan

    Joined:
    Aug 17, 2012
    Posts:
    384
    I know. That's why I said it would need modification.
     
  44. pbhogan

    pbhogan

    Joined:
    Aug 17, 2012
    Posts:
    384
    It works for me. I just tested it to confirm. Are you running the latest version of InControl? 1.5.5?
     
  45. pbhogan

    pbhogan

    Joined:
    Aug 17, 2012
    Posts:
    384
    I've added some additional information here: http://www.gallantgames.com/pages/incontrol-new-unity-gui
     
  46. pbhogan

    pbhogan

    Joined:
    Aug 17, 2012
    Posts:
    384
    The following should work better for you:

    Code (CSharp):
    1.  
    2. new InputControlMapping {
    3.   Handle = "ZoomIn",
    4.   Target = InputControlType.RightTrigger,
    5.   Source = MouseScrollWheel,
    6.   SourceRange = InputRange.ZeroToNegativeInfinity,
    7.   Invert = true,
    8.   Raw = true,
    9.   Scale = 1.0f
    10. },
    11. new InputControlMapping {
    12.   Handle = "ZoomOut",
    13.   Target = InputControlType.LeftTrigger,
    14.   Source = MouseScrollWheel,
    15.   SourceRange = InputRange.ZeroToPositiveInfinity,
    16.   Raw = true,
    17.   Scale = 1.0f
    18. }
    19.  
    It's a bit non-intuitive, but when Raw = true, TargetRange is ignored, so you need to use Invert = true instead. Also you need zero to +- infinity since mouse values are often greater than zero.
     
  47. pbhogan

    pbhogan

    Joined:
    Aug 17, 2012
    Posts:
    384
    I'm not sure I entirely understand. Do you mean you want absolute mouse position instead of relative? It doesn't make sense to use absolute mouse position for a virtual controller. InControl mimics what it would be like to use a controller stick, so relative mouse deltas between frames is more useful for that, with zero being returned when the mouse is not moving. You should be adding this value to your camera, not setting it to this value.

    Incidentally, TargetRange is ignored when Raw = true so you could remove those lines.
     
  48. rsodre

    rsodre

    Joined:
    May 9, 2012
    Posts:
    229
    I use the right stick on my xbox controller to hover a camera above a 3rd person player.
    So when I want to see the player from from above, I put sticker up and hold i as long as I want, then release the sticker and the camera comes back to relaxed position, behind the player.

    I guess there's no way to simulate the holding with the mouse.
    It would be nice to have a a flag to hold the sticker, not release it.

    thanks for the gui info, I'll try it out.
     
  49. Just in case you weren't aware or for those on Unity 5.1 wanting to make the modification, there's a define "UNITY_5" that exists.
     
  50. username132323232

    username132323232

    Joined:
    Dec 9, 2014
    Posts:
    477
    Yes, I have 1.5.5 build 5366. I got the Back button work with Key.Escape, but InputControlType.Back doesn't seem to work at all. Perhaps I didn't set everything up correctly?