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. dgoyette

    dgoyette

    Joined:
    Jul 1, 2016
    Posts:
    4,195
    I was wondering what the correct approach was for resetting some, but not all, bindings in a PlayerAction to a default state? For example, I have PlayerActions that have a mix of Keyboard bindings and Controller bindings. On my input screen, I let the player reset the Keyboard inputs, or reset the Controller inputs, with two distinct buttons. Because I don't want to reset every binding (only the keyboard bindings, or only the controller bindings) I can't use 'ResetBindings', since that would reset everything. Instead, I'm instantiating a copy of my PlayerActionSet, and using ReplaceBinding to replace the binding with the copy. Unfortunately, that results in "Binding source is already bound to action" warnings. It doesn't seem possible to clear the BoundTo field on the copy to avoid this.

    Is there a general approach to making one binding take on the characteristics of another? Or do I need to test what concrete BindingSource type the object is, instantiate a new one, a manually assign all of the public properties?

    Edit: I did end up just creating a utility method to return a "copy" of a binding, by newing up a binding and setting its values. I didn't handle every possible case, because I didn't need everything, but here's the code I wrote:

    Code (CSharp):
    1.         public static BindingSource CopyBinding(BindingSource binding)
    2.         {
    3.             BindingSource newBindingSource = null;
    4.             if (binding is DeviceBindingSource)
    5.             {
    6.                 var existingDeviceBinding = (DeviceBindingSource)binding;
    7.                 newBindingSource = new DeviceBindingSource(existingDeviceBinding.Control);
    8.             }
    9.             else if (binding is KeyBindingSource)
    10.             {
    11.                 var existingKeyBinding = (KeyBindingSource)binding;
    12.                 newBindingSource = new KeyBindingSource(existingKeyBinding.Control);
    13.             }
    14.             else if (binding is MouseBindingSource)
    15.             {
    16.                 var existingMouseBinding = (MouseBindingSource)binding;
    17.                 newBindingSource = new MouseBindingSource(existingMouseBinding.Control);
    18.             }
    19.             else
    20.             {
    21.                 throw new InvalidOperationException($"{binding.GetType()} not supported");
    22.             }
    23.  
    24.             return newBindingSource;
    25.         }
     
    Last edited: Dec 31, 2019
  2. dgoyette

    dgoyette

    Joined:
    Jul 1, 2016
    Posts:
    4,195
    This seems like a fairly complicated way to try to answer what seems like a fairly simple question: Is the player currently using Keyboard & Mouse, or are they using a Controller? I'm trying to find a reliable way to determine that. I've tried to use the approach mentioned here, to look at the LastInputType on various PlayerActionSets, but there's a downside to that: it only fires when one of the specific PlayerActions in the PlayerActionSet is used.

    Is there any lower-level information I can access to learn that the last device that generated some input (even unused input) was keyboard, mouse, or controller? I'm trying to set up some common behavior where if the player does something on a controller, the screen changes to show some controller-specific content. But then, ideally, if they move the mouse or press any key on the keyboard, that controller-ui content will be hidden. The LastInputType only works if the player happens to press one of the buttons associated with a PlayerAction. And very often there are no player actions associated with mouse movement on Pause/Menu screens.

    Anyway, I'm hoping I'm just missing something simple here. Just trying to answer the question of whether, at any given moment, the player is using the Mouse & Keyboard, or the Controller.
     
  3. pbhogan

    pbhogan

    Joined:
    Aug 17, 2012
    Posts:
    384
    I'm afraid there's no shortcut here. I think the way to try do it would be to check for mouse position changes (store the current mouse position each frame and next frame check if it's different, maybe with some minimum delta to exclude mouse jitter) and also use Input.anyKey to check for key/mouse button presses. If there is key/mouse activity, compare InputManager.CurrentTick against the LastInputTick of all devices in InputManager.ActiveDevices. If the former is larger then keyboard/mouse has last produced input otherwise a controller. Ideally, this should run after InControl updates either using script execution order, or you could hook into InputManager.OnCommitDevices which fires once all devices have fully updated and committed state.
     
    dgoyette likes this.
  4. dgoyette

    dgoyette

    Joined:
    Jul 1, 2016
    Posts:
    4,195
    Okay. Thanks for confirming there isn't a simple alternative. I don't mind some code complexity as long as I'm not reinventing the wheel.
     
  5. Grhyll

    Grhyll

    Joined:
    Oct 15, 2012
    Posts:
    119
    Uh I don't mean to be annoying or anything, but is there a reason why you won't answer my question about supporting vibrations for PS4 pads on Windows? It's not even so I can decide if I want to use InControl or not, since I've been using it anyway for years and loving it, it's just so I can know if I have to find a way to do it myself or if it might be available before the game I'm working on is released, so I don't have to worry about it.
     
  6. dgoyette

    dgoyette

    Joined:
    Jul 1, 2016
    Posts:
    4,195
    This mostly worked. The only snag was that Input.anyKey also picks up joystick buttons. I took an extra step of making sure the that none of the joystick buttons was pressed, and it seems to work pretty well.

    I'll probably find issues with this code in the future, but for now this is what I'll be going with. The only non-standard stuff here is my SubscriptionDirector which I use to notify other parts of my game that the input changed. Happy to be informed if any of this looks suspect.

    The basic idea is that if we're in GamepadMode, we check for keyboard/mouse inputs to know if we should switch to keyboard and mouse mode. Similarly, if we're not currently in GamepadMode, we check if the gamepad has input this frame. Note that I didn't keep track of the last keyboard update tick. Instead, I'm just checking whether the ActiveDevice was updated this tick. The code in Start() handles the active device changing

    Code (CSharp):
    1.  
    2.  
    3. void Start()
    4. {
    5.     // See MonitorForInputDeviceChange() for full information on device tracking.
    6.     InputManager.OnActiveDeviceChanged += inputDevice =>
    7.     {
    8.         InGamepadMode = true;
    9.         CurrentGamepadDevice = inputDevice;
    10.  
    11.         SubscriptionDirector.Instance.Publish(SubscriptionType.InputDeviceChanged, new InputDeviceChangedSubscriptionPayload()
    12.         {
    13.             InGamepadMode = InGamepadMode,
    14.             GamepadDevice = CurrentGamepadDevice
    15.         });
    16.     };
    17. }
    18.  
    19.  
    20. void Update()
    21. {
    22.     MonitorForInputDeviceChange();
    23. }
    24.  
    25.  
    26. // This is based on guidance from https://forum.unity.com/threads/incontrol-input-and-cross-platform-controller-support-for-unity-made-easy.257619/page-12#post-5296677
    27. private void MonitorForInputDeviceChange()
    28. {
    29.     // This method is partially responsible for monitoring for input and decide generally whether the player is currently
    30.     // using Mouse&Keyboard, or a controller. There are three cases we need to test for:
    31.     //  1. Currently in Mouse & Keyboard mode, but a gamepad was used.
    32.     //  2. Currently in Gamepad mode, but started using Mouse & Keyboard  
    33.     //  3. Currently in Gamepad mode, but started using a different gamepad.
    34.     // For efficiency, we try to avoid looking at inputs that don't matter. So, if we're in Mouse and Keyboard
    35.     // mode, we don't keep looking for mouse and keyboard input. We only look for gamepad input. It may seem like we'd
    36.     // need to look for gamepad input even if we're in gamepad mode, but actually changes to the gamepad device are handled
    37.     // via the OnActiveDeviceChanged in the InputManager. So this method only actually handles cases 1 and 2, while case
    38.     // 3 is handles via OnActiveDeviceChanged
    39.  
    40.     bool hasChange = false;
    41.     if (InGamepadMode)
    42.     {
    43.         // We're in Gamepad mode. See if we should switch to Mouse and Keyboard.
    44.         // We do this if we get any non-joystick key input, or we get mouse input.
    45.         if (Input.anyKeyDown || Input.GetAxis(UnityConstants.Axes.MouseX) != 0 || Input.GetAxis(UnityConstants.Axes.MouseY) != 0)
    46.         {
    47.             if (!JoystickKeyDown())
    48.             {
    49.                 // It wasn't a joystick key. Switch to Keyboard mode.
    50.                 InGamepadMode = false;
    51.                 CurrentGamepadDevice = null;
    52.                 hasChange = true;
    53.  
    54.             }
    55.         }
    56.     }
    57.     else
    58.     {
    59.         // We're in Mouse & Keyboard mode. See if there's an ActiveDevice which received input this frame.
    60.         // If so, we switch to that gamepad.
    61.         if (InputManager.ActiveDevice != null
    62.             && InputManager.ActiveDevice.LastInputTick == InputManager.CurrentTick)
    63.         {
    64.             InGamepadMode = true;
    65.             CurrentGamepadDevice = InputManager.ActiveDevice;
    66.             hasChange = true;
    67.         }
    68.     }
    69.  
    70.     if (hasChange)
    71.     {
    72.         SubscriptionDirector.Instance.Publish(SubscriptionType.InputDeviceChanged, new InputDeviceChangedSubscriptionPayload()
    73.         {
    74.             InGamepadMode = InGamepadMode,
    75.             GamepadDevice = CurrentGamepadDevice
    76.         });
    77.     }
    78. }
    79.  
    80. private bool JoystickKeyDown()
    81. {
    82.     for (int keyIndex = 0; keyIndex < _rawJoystickKeycodes.Length; keyIndex++)
    83.     {
    84.         if (Input.GetKeyDown(_rawJoystickKeycodes[keyIndex]))
    85.         {
    86.             return true;
    87.         }
    88.     }
    89.  
    90.     return false;
    91. }
    92.  
     
  7. pbhogan

    pbhogan

    Joined:
    Aug 17, 2012
    Posts:
    384
    Sorry, it's unlikely to come soon at this point. I've taken a few stabs at it without success.
     
    Grhyll likes this.
  8. cloverme

    cloverme

    Joined:
    Apr 6, 2018
    Posts:
    197
    Is there a way to force the update of the buttonmapping handle names? So that "Action3" turns into "Square" for Ps4 for example...It does happen after a rebinding event for any input, but I can't seem to find anything to call to force it on my own. Use Fixed Update doesn't seem to be doing it, so I figure there's something else I can call that will do it?

    When I create the default mappings, I'm binding an action "fire" to Action3 for a generic controller. But if the player has a Ps4 controller plugged in, all the buttonmapping handle names stay as the default until I do a remapping, then they all update to the Ps4 types. So I just want to be able to "force" that call on my own but can't seem to figure out what does it.
     
  9. pbhogan

    pbhogan

    Joined:
    Aug 17, 2012
    Posts:
    384
    Technically, it updates the names as soon as a device is considered active (or the active device changes). Rebinding would cause that too since it's obvious the device that pressed the button is now active. But before that, it has no idea which devices are relevant.

    So, for example, lets say you have 4 controllers attached:
    1. Xbox One
    2. PlayStation 4
    3. Nintendo
    4. A broken, unknown or non-responsive controller.

    Now, you make an action set and add some default bindings. Which control names should it use? It's ambiguous. And if you arbitrarily pick one, let's say the first one.

    What if (1) was the broken controller? Note, InControl does not know when a controller is broken or non-responsive.

    What if this is the second action set you're creating? Multiple input sets can listen to the same device. This is a frequent use case to separate game and menu input, for example.

    It gets trickier because you can change (after you've added bindings) which devices the action set should include or exclude for listening.

    What happens if there were no devices at the time the bindings were added? What if the device you pick arbitrarily disconnects soon after? What if happens if another device connects?

    So, all this is to say, it gets extremely non-trivial to decide which names to use and when to update them, until the moment a device gives input.

    I could, and probably should, add something to the API where you can do something like actionSet.SetDefaultDeviceContext( InputDevice device ); and it'll just use what you tell it for better or worse. Which lets you choose... but of course then you need to ask yourself all these questions and more.

    If you know it's only going to listen to a single device, you could just set actionSet.Device = inputDevice and that's the one it'll use because you've been explicit about it. Otherwise it'll use the first active device it finds after filtering them with IncludeDevices and ExcludeDevices. So you could also force a device to become active, although this currently requires calling an internal method so you'd need to change that to public: inputDevice.RequestActivation();

    Okay, but what should you do. Here's my recommendation:

    Don't use binding names for DeviceBindingSource. Rather, use DeviceBindingSource.Control which is of InputControlType, and combine that with the PlayerAction/PlayerActionSet's LastDeviceStyle property in a lookup table for icons instead, and as a fallback use Xbox icons, or, even better, something neutral like many games do like the diamond of four buttons with just the one you intend filled in and the rest empty circles.
     
  10. lazylukey

    lazylukey

    Joined:
    May 26, 2017
    Posts:
    36
    @pbhogan This bug reported by malyKuba still seems to be around in the v1.7.4. I am using Unity 2019.2.16f1. Is there any workaround for it?
     
  11. pbhogan

    pbhogan

    Joined:
    Aug 17, 2012
    Posts:
    384
    Huh. I seem to have missed that one.

    Here's how I'll fix it in the next update. In InControlManager.cs, add:
    bool applicationHasQuit = false;

    In OnApplicationQuit() add:
    applicationHasQuit = true;

    In Update() and FixedUpdate() add:
    if (applicationHasQuit) return;
     
  12. dgoyette

    dgoyette

    Joined:
    Jul 1, 2016
    Posts:
    4,195
    Any thoughts on this one, @pbhogan? Is there a known issue where XBox360 controllers are misidentified as XBoxOne controllers?
     
  13. pbhogan

    pbhogan

    Joined:
    Aug 17, 2012
    Posts:
    384
    I'd need to see the output of the TestInputManager scene to know for sure, but my guess is it's happening with XInput enabled. Microsoft's XInput API provides no identifying information about the underlying hardware, so InControl has no idea what exact controller it is other than it's an XInput-compatible controller... which means it's either an Xbox 360 or Xbox One controller (or a third-party version of one of these) and I had to pick one for the device style representation, so I picked the newer one.

    The same goes for the UWP gamepad API incidentally. It's a weird omission by Microsoft, but it is what it is. ¯\_(ツ)_/¯
     
  14. dgoyette

    dgoyette

    Joined:
    Jul 1, 2016
    Posts:
    4,195
    Yes, this is with XInput enabled. So basically, XInput can't tell XBox360 from XBoxOne? Okay. I'll see what I can do to work around that. Thanks for the confirmation.
     
  15. TCROC

    TCROC

    Joined:
    Aug 15, 2015
    Posts:
    230
    The TouchControlManager.cs script throws a Null Reference Exception. Modifying line 541 to be
    var touchControlCount = touchControls?.Length;
    instead of
    var touchControlCount = touchControls.Length;
    fixes the error.

    Controls Enabled is always marked as true in the inspector as well, even if it is false.

    The current workaround is to check it on / off once and it fixes itself.

    Not sure what is causing that one.

    Current version of Unity = 2019.2.13f1.

    TouchControlManager is a prefab and being modified in the prefab editor.
     
  16. bigpants

    bigpants

    Joined:
    Dec 9, 2009
    Posts:
    49
    (not an emergency, and apologies if you've already addressed this)
    I'm using Unity 2020.1.0a (alpha) and InControl 1.7.2 is working well!
    PC using old Unity control system - XBOX 360 controller, mouse and keyboard.

    However, I cannot get the latest InControl 1.74.
    PackageManager only lists/downloads 1.7.2
    I can download the 1.7.4 .unitypackage file from your site,
    BUT I don't think I can import that anymore in 2020 - it needs a .json file even for disk import.

    NOT an emergency, just FYI.
     
  17. pbhogan

    pbhogan

    Joined:
    Aug 17, 2012
    Posts:
    384
    I don't know what to tell you... I haven't had that problem at all with Unity 2020. I just checked with 2020.1.0a19 (latest as of writing) and it shows 1.7.4 and imports fine.

    Maybe there's some package cache that is corrupted. ¯\_(ツ)_/¯
     
  18. pbhogan

    pbhogan

    Joined:
    Aug 17, 2012
    Posts:
    384
    I'll take a look... it's probably related to being a prefab.
     
  19. bigpants

    bigpants

    Joined:
    Dec 9, 2009
    Posts:
    49
    I'm using 2020.1.0a18.
    I just tried a FRESH new project and only 1.7.2 is shown.
    I think that rules out the package cache (unless that's shared between Unity projects).
    At some point I will upgrade to 2020.1.0a19 and see if that fixes it.
     
  20. pbhogan

    pbhogan

    Joined:
    Aug 17, 2012
    Posts:
    384
    I'm pretty sure the package caches are system level and shared between projects on some level. But I'm not sure how Unity deals with assets since they're not really packages. There's an asset store cache too somewhere on the system so maybe you need to find that and delete it.

    In any event, it's a Unity issue, not InControl. I didn't have any problems with any of the previous 2020.1.0a releases either.
     
  21. bigpants

    bigpants

    Joined:
    Dec 9, 2009
    Posts:
    49
    PROBLEM FIXED (see above postings)

    Details:
    Unity 2020.1.0a18 (fresh new project) ONLY showing InControl 1.7.2 - NO option to download latest 1.7.4.
    (I used InControl 1.7.2 in an older Unity 2018 project)

    Solution:
    Downloaded packages (imported into project or not) are cached.
    Delete the "Gallant Games" folder, and package manager will display 1.7.4
    (presumably goes to the online store now, rather than just your local drive)
    C:\Users\yourname\AppData\Roaming\Unity\Asset Store-5.x\Gallant Games
     
  22. Player7

    Player7

    Joined:
    Oct 21, 2015
    Posts:
    1,533
    Any update on this with the Unity input system now?
     
  23. drinkycode

    drinkycode

    Joined:
    Sep 28, 2014
    Posts:
    7
    @pbhogan It's been a little while since the last update and I was wondering if InControl has plans in the future to support some of the improvements added in iOS 13 (https://developer.apple.com/videos/play/wwdc2019/616/) especially for handling both the Share (PS4) and View (Xbox One) buttons (right now they all map the same as the home/menu button ala MFi controls).
     
  24. pbhogan

    pbhogan

    Joined:
    Aug 17, 2012
    Posts:
    384
    As it happens, yes, I've got this in for the next update. It'll also have MFi support for Mac, although that is a bit more experimental at the moment (and will be labelled as such). But MFi on iOS should be good to go. Both will be part of the native input plugin directly using Apple's Game Controller framework. The update has a number of other additions and internal changes which has held up release, but I'm hoping to get it out soon.

    If you're interested in trying it out, keep an eye out on the downloads page (http://www.gallantgames.com/downloads) for a new beta in the next few days. It will probably be labelled version 1.8.0
     
    Grhyll and drinkycode like this.
  25. drinkycode

    drinkycode

    Joined:
    Sep 28, 2014
    Posts:
    7
    That sounds great! We'd be happy to take a look at the beta and implement it in our current game (and hopefully provide feedback for that too).
     
  26. pbhogan

    pbhogan

    Joined:
    Aug 17, 2012
    Posts:
    384
    It's up now at http://www.gallantgames.com/downloads

    You'll need to create an account and add your InControl license to see the relevant package. Look for 1.8.0 beta
     
    mlee_schell likes this.
  27. drinkycode

    drinkycode

    Joined:
    Sep 28, 2014
    Posts:
    7
    @pbhogan Testing out the InControl 1.8.0 beta, everything looks good up until I need to archive the release for uploading to the App Store. When I try to archive, I get the following error:


    ld: bitcode bundle could not be generated because 'XXX/Libraries/InControl/Plugins/iOS/InControlNative.a(main.o)' was built without full bitcode. All object files and libraries for bitcode must be generated from Xcode Archive or Install build for architecture arm64


    It looks like the plugin might need a recompile to force bitcode (ala this issue: https://stackoverflow.com/questions/31233395/ios-library-to-bitcode). Thanks for your support with maintaining this plugin!
     
  28. pbhogan

    pbhogan

    Joined:
    Aug 17, 2012
    Posts:
    384
    I've uploaded a new package that includes binaries with the embed bitcode flag. Would you give that a go please?
     
    drinkycode likes this.
  29. AnomalusUndrdog

    AnomalusUndrdog

    Joined:
    Jul 3, 2009
    Posts:
    1,553
    Hi, apologies if this has already been answered, but the search-in-thread function showed nothing:

    From what I understand, it's not possible to bind a modifier key plus mouse button (example: Shift + Left Click).

    The easiest way I can see doing this is modify KeyBindingSource to optionally have mouse buttons in them too, or maybe an entirely new BindingSource class altogether. Maybe I can use KeyBindingSource as a starting point. But basically from what I see I need to somehow combine KeyBindingSource's key detection plus MouseBindingSource's mouse button detection. Is that correct?

    Note: I'm on v1.7.2 since the project is still on Unity 5.5, we don't have time to do an update to the latest version of Unity in the middle of production right now. I don't know if the latest version has added what I'm looking for.
     
  30. paulogodinhoaq

    paulogodinhoaq

    Joined:
    Aug 22, 2018
    Posts:
    5
    Hi, we are using Unity 2019.3.3f1 with InControl 1.7.4 on Apple TV and it looks like MENU button on the Remote Control(Siri Controller) is not being recognized, the TestInputManager Scene shows all button being pressed but this one. It also happens with both middle center buttons from the Xbox One controller(back and start) when they are connected to the Apple TV, they don't show as pressed on the test scene.
     
  31. pbhogan

    pbhogan

    Joined:
    Aug 17, 2012
    Posts:
    384
    I made an experimental ComboBindingSource a while back. I think it might still work. You can check it out here: https://gist.github.com/pbhogan/6ad47df1331da9353cbd3717effbc7a1
     
    AnomalusUndrdog likes this.
  32. pbhogan

    pbhogan

    Joined:
    Aug 17, 2012
    Posts:
    384
    Try the 1.8.0 beta available here: http://www.gallantgames.com/downloads

    Unity changed some mappings for iOS, but also the beta (with native input enabled) includes native support for Apple's Game Controller API which should fully support all the controllers and additional buttons made available in iOS/tvOS 13+
     
    drinkycode and paulogodinhoaq like this.
  33. drinkycode

    drinkycode

    Joined:
    Sep 28, 2014
    Posts:
    7
    That worked @pbhogan and archived successfully! Thanks!
     
  34. dgoyette

    dgoyette

    Joined:
    Jul 1, 2016
    Posts:
    4,195
    I had a remote tester try my game, and ran into problems because his DeviceClass was "Unknown". I'm trying to track down the person and find out what controller they were using, but I see this in their log file:

    [InControl] Joystick 1: "Controller (GAME FOR WINDOWS)"

    Is this just a super generic kind of controller than can't be mapped to a real controller? Just trying to decide how I should handle this.
     
  35. pbhogan

    pbhogan

    Joined:
    Aug 17, 2012
    Posts:
    384
    Yes, it's almost certainly a generic controller that is unknown to InControl. A mapping profile can most likely be created (unless the controller just doesn't work in some way) but it requires some work to make the profile and, importantly, requires having the physical controller present to figure it out.

    I do try to buy many commonly used and requested controllers to add and maintain support for them, but obviously I can't buy or obtain every esoteric generic or cloned controller out there.

    Since you don't have the controller yourself you probably won't want to do this, but should you (or anyone else) need to know how to make mapping profiles, you can consult this outline: https://gist.github.com/pbhogan/34096baa4e619e4b9db0b0093d89541e

    One thing I do recommend is enabling XInput (either the managed version without native input, or the version included in native input). This will vastly increase compatibility for Xbox controller clones, which makes up a significant chunk of cheap, off-brand controllers. It should also allow users to use tools like x360ce to map generic controllers themselves.
     
    dgoyette likes this.
  36. WryMim

    WryMim

    Joined:
    Mar 16, 2019
    Posts:
    69
    Hello, do I understand correctly that there is no smoothing? Why didn't you add it, even if there was one in Unity Input? This is not a downground? Sorry if it's rude.
     
  37. WryMim

    WryMim

    Joined:
    Mar 16, 2019
    Posts:
    69
    Tell me more. I understand correctly that if I want multiple bindings, I need to use "PlayerActionSet", because "InputManager.ActiveDevice.Action1" is not suitable for this? For example, I need to bind 3 keys to a single action.
     
  38. WryMim

    WryMim

    Joined:
    Mar 16, 2019
    Posts:
    69
    Not work on Unity 2020.1.0b5
    upload_2020-4-20_10-22-33.png


    => [fb]
     
  39. DevinDazzlr

    DevinDazzlr

    Joined:
    Dec 3, 2013
    Posts:
    6
    I have run into an issue with InControl 1.8.1 using version 2019.3.12f of Unity 2019 and using Visual Studio 2017:

    When I import InControl from the package manager into a new project, I get the following issue when adding "using InControl;" in Visual Studio 2017:

    The type or namespace name 'InControl' could not be found (are you missing a using directive or an assembly reference?)

    The funny thing is, the game runs in Unity and I am able to compile the game to an executable and run it.
     
    Last edited: May 8, 2020
  40. pbhogan

    pbhogan

    Joined:
    Aug 17, 2012
    Posts:
    384
    Are you using assembly definitions in your project? You may need to add a reference to InControl if so. But if it's working in Unity and builds, then it could be something else.

    I've run into a similar situation using JetBrains Rider from time to time where it's like the project / solution files aren't getting generated properly by Unity and I have to go through a dance of closing Unity and Rider, deleting the project files (and sometimes other temporary project files like Library and obj) and then reopen Unity and have it regenerate.

    I have no idea what causes it, but it seems to be a bug with Unity's project generation or caching of assemblies or something like that.
     
    DevinDazzlr likes this.
  41. DevinDazzlr

    DevinDazzlr

    Joined:
    Dec 3, 2013
    Posts:
    6
    I think it was isolated to 2019.3.12f because I just updated to 2019.3.13f, and the problem went away. I imported InControl via Package Manager in a new project in 2019.3.12f, and the issue was present even without me doing anything else than creating a new project and importing InControl via Package Manager - but in 2019.3.13f there is no issue.

    Anyway, updating to latest version of Unity solved the issue for me :) Thank you for taking the time to reply to my post :)
     
  42. pbhogan

    pbhogan

    Joined:
    Aug 17, 2012
    Posts:
    384
    Hopefully it is an isolated case! I do get it from time to time in various versions. But I use all kinds of beta things including the Rider betas, so maybe it's something with that for me. ¯\_(ツ)_/¯
     
  43. CosmicStud

    CosmicStud

    Joined:
    Jun 13, 2017
    Posts:
    55
    @pbhogan Hello, I have a small problem where a playstation 4 controller doesn't register well on the Android connected via bluetooth. I installed from the asset store, with a fresh install with 2019.3.11f on Mac OS.

    Building out to IOS, MAC, works fine with the bluetooth setup. Android works fine as well with the standard Unity UI, but it seems to not register my actions beyond the UI. The touchpad actually registers as a mouse.

    Under the input manager, there is no active device, unknown name as well. The controller is a ps4 controller that is named "Wireless Controller" in the android bluetooth settings. Just wondering what am I missing? Besides that, thank you!

    Update: I've opened a new project with 2019.3.11, 3.12, 3.13, as well as 2018.4 all fresh with nothing but Incontrol and the TestInputScene. After building out to my LG K20, Pixel C, and Galaxy S10 all different android OS versions. Using the Ps4 controller and then a Nvidia Shield controller on bluetooth as well as wired. It seems Incontrol and Android doesnt detect the controllers well as it registers as a Android TV remote. What can I do to fix this issue?
     
    Last edited: May 16, 2020
  44. tswiecki

    tswiecki

    Joined:
    Jul 4, 2015
    Posts:
    5
    I've got exactly same problem. Both PS4 and NVidia Shield (2017) controllers register as Android TV (InputDevice.Name) - InControl version 1.8.1

    Nvidia Shield Controller attached to the Nvidia Shield device behaves the same way - InputDevice.Name = Android TV. LeftStick and RightStick don't work. DPad works fine.
     
    Last edited: May 17, 2020
  45. pbhogan

    pbhogan

    Joined:
    Aug 17, 2012
    Posts:
    384
    If you're using 1.8.0 or 1.8.1, please e-mail me and I'll give you a package to try. Or if you create an account on my site and add your Asset Store license, you can download the beta package from there: http://www.gallantgames.com/downloads

    There's currently a bug in the identification of certain devices. I should be pushing this update soon (look for 1.8.2 in the Asset Store later this week).
     
  46. Alloc

    Alloc

    Joined:
    Jun 5, 2013
    Posts:
    241
    Hi Patrick,

    just updating to 1.8.0 (finally, we were still on 1.6.7, but that shows how well it worked :) ). Was wondering why there's quite a bunch of code still calling the UnityEngine.Debug methods directly instead of going through InControl.Logger?

    Regards,
    Chris
     
  47. Alloc

    Alloc

    Joined:
    Jun 5, 2013
    Posts:
    241
    PS: The reason I updated was in hope for a fix for a crash with the native input module that we had for a long time now.
    Unfortunately 1.8.0 is the same in that regard. It crashes when the native module including XInput is enabled, a controller is used at least once during the game and then the game is quit. Without the native input module or without XInput it works fine.

    This is the trace that's logged when the game crashes on quit:
    Code (csharp):
    1.  
    2. ========== OUTPUTTING STACK TRACE ==================
    3.  
    4. 0x00007FF97745F572 (gameoverlayrenderer64) VulkanSteamOverlayProcessCapturedFrame
    5. 0x00007FF95C56D499 (UnityPlayer) win::RawInput::HidDevice::UpdateStateFromXInput
    6. 0x00007FF95C56724A (UnityPlayer) win::RawInput::HidDevice::OnInput
    7. 0x00007FF95C56D09D (UnityPlayer) win::RawInput::HidDevice::UpdateState
    8. 0x00007FF95C56D43D (UnityPlayer) win::RawInput::UpdateState
    9. 0x00007FF95C56B966 (UnityPlayer) win::Input::Process
    10. 0x00007FF95C56BC5E (UnityPlayer) win::RawInput::Process
    11. 0x00007FF95C5839D9 (UnityPlayer) PerformMainLoop
    12. 0x00007FF95C58245A (UnityPlayer) MainMessageLoop
    13. 0x00007FF95C586491 (UnityPlayer) UnityMainImpl
    14. 0x00007FF95C589DDB (UnityPlayer) UnityMain
    15. 0x00007FF6DE9811F2 (7DaysToDie) __scrt_common_main_seh
    16. 0x00007FF9FAAB4034 (KERNEL32) BaseThreadInitThunk
    17. 0x00007FF9FD5B3691 (ntdll) RtlUserThreadStart
    18.  
    19. ========== END OF STACKTRACE ===========
    20.  

    Current environment: Unity 2019.2.17, InControl 1.8.0, Windows 10 Pro, XBox One Wireless Controller.
    At least the OS, Unity and InControl versions didn't seem to matter much, all of those were lower when we first experienced this issue.

    Do you have any pointers on what the reason might be?
     
  48. pbhogan

    pbhogan

    Joined:
    Aug 17, 2012
    Posts:
    384
    It's mostly an oversight. I'll try to get that cleaned up for the next update.
     
    Alloc likes this.
  49. pbhogan

    pbhogan

    Joined:
    Aug 17, 2012
    Posts:
    384
    Yes, we've recently figured out how to solve this. It appears that, whatever Steam injects into the system to handle its controller support, does not like when the game reinitializes input APIs while Steam still has its hooks in. To be clear, this is a Steam bug/issue.

    Fortunately, the fix is fairly simple... make sure InControl does not reinitialize once your game has loaded. The way to do this is ensure every instance of the InControl Manager in any of your scenes has "Do Not Destroy On Load" turned on in the InControl Manager inspector. Or, if you're doing something more custom, don't call InputManager.Reset() until application shutdown.

    When the InControl manager game object destroys, it also tears down InControl and thus the native plugin shuts down all its handles to system input APIs. When the object enables in a new scene it initializes everything again.

    In general, it's a best practice to avoid reinitialization anyway to avoid the additional work on every scene load, even though it's safe to do outside of Steam. So "Do Not Destroy On Load" has been on by default for a long time. Even with it turned on, it's safe to have a manager in every scene—a common practice for convenience starting arbitrary scenes in the editor. The manager has code to ensure there will be no duplicates in the scene, destroying itself if it sees another one already exists.
     
  50. Alloc

    Alloc

    Joined:
    Jun 5, 2013
    Posts:
    241
    Pretty sure we don't do anything like that, but I'd check it ... There's no InputManager.Reset method though ;) I suppose you meant Reload?

    PS: If so, Reload is never called at all.