Search Unity

Input System Update

Discussion in 'New Input System' started by Rene-Damm, Dec 12, 2017.

  1. rorylane

    rorylane

    Joined:
    Apr 10, 2013
    Posts:
    22
    Hi everybody. Is this worth using yet for a project using Vive?

    I'm working on a new Cross-Platform Input Module for AR/VR.

    As I got started on it, I became aware of this new Input System. It seems great conceptually, and appears to solve a lot of the issues that have forced me into the Cross-Platform Input-Module business in the first place.

    But, I've not gotten it to receive Vive Input, and it seems a little premature maybe to attempt to incorporate this new package into a real project. Then again, I'm unfamiliar with how it works, and it's possible I'm doing something wrong.

    I'm using Unity 2019.3.0a5 and a Package generated from the "develop" branch of the GIT Repo https://github.com/Unity-Technologies/InputSystem.git.

    I've tried most of the obvious Option Binding options available, which are somewhat nebulous.
    HR_Controller_Options.jpg
    In the Input Debugger, it lists the HTC Vive in the "Unsupported" category, but with several Device IDs with the "HTC" Prefix.

    Input_Debugger.jpg



    I can get mouse and keyboard input, but I haven't been able to register an event for anything generated from the Vive or the Vive Controllers.

    Is this worth pursuing, or should I check back in a few months from now?
     
    ROBYER1 and scvnathan like this.
  2. Ziron999

    Ziron999

    Joined:
    Jan 22, 2014
    Posts:
    238
    I have started using this and so far it seems to be a much better way to do things. The only thing i've always had in update is input which always caused problems for me. Now that this is possible I will have NOTHING in updates. This is just amazing.

    I would like to know how to do conditionals though. It seems like i have to make a separate interaction for every single possible thing which starts to create a ton of callbacks.

    How do you do this for example:
    Code (CSharp):
    1.     int minX = -120;
    2.     public static int maxX = 120;
    3.     int minZ = -200;
    4.     int maxZ = 110;
    5.     int multiplier = 100;
    6.     Vector3 v3Cam;
    7.  
    8.     void InitWASD()
    9.     {
    10.         v3Cam = Camera.main.transform.position;
    11.     }
    12.  
    13.     float CalculateDirection(float value, float min, float max)
    14.     {
    15.         if (Input.GetKey(KeyCode.LeftShift))
    16.             return Mathf.Clamp(value + (multiplier * 2 * Time.deltaTime), min, max);
    17.         else
    18.             return Mathf.Clamp(value + (multiplier * Time.deltaTime), min, max);
    19.     }
    20.  
    21.     float CalculateDirectionReverse(float value, float min, float max)
    22.     {
    23.         if (Input.GetKey(KeyCode.LeftShift))
    24.             return Mathf.Clamp(value - (multiplier * 2 * Time.deltaTime), min, max);
    25.         else
    26.             return Mathf.Clamp(value - (multiplier * Time.deltaTime), min, max);
    27.     }
    28.  
    29.     void WASDUpdate()
    30.     {
    31.         if (!BC_Singleton.Instance.SceneGlobals.InUpgrading)
    32.         {
    33.             if (Input.GetKey(KeyCode.D))
    34.             {
    35.                 var tempMaxX = maxX;
    36.                 if (BC_Singleton.Instance.SceneGlobals.IsBuildingMenuOpen)
    37.                     tempMaxX = maxX + 35;
    38.                 v3Cam.x = CalculateDirection(v3Cam.x, minX, tempMaxX);
    39.                 Camera.main.transform.position = v3Cam;
    40.             }
    41.             if (Input.GetKey(KeyCode.A))
    42.             {
    43.                 v3Cam.x = CalculateDirectionReverse(v3Cam.x, minX, maxX);
    44.                 Camera.main.transform.position = v3Cam;
    45.             }
    46.             if (Input.GetKey(KeyCode.W))
    47.             {
    48.                 v3Cam.z = CalculateDirection(v3Cam.z, minZ, maxZ);
    49.                 Camera.main.transform.position = v3Cam;
    50.             }
    51.             if (Input.GetKey(KeyCode.S))
    52.             {
    53.                 v3Cam.z = CalculateDirectionReverse(v3Cam.z, minZ, maxZ);
    54.                 Camera.main.transform.position = v3Cam;
    55.             }
    56.         }
    57.     }
    To be more specific, how would you handle shift?
    Also, how many callbacks do you think can be handled before a system starts to eat bricks?
     
  3. Ziron999

    Ziron999

    Joined:
    Jan 22, 2014
    Posts:
    238
    I have successfully done this. Wow this is a better structure. Less methods + faster?
    Code (CSharp):
    1.     void InitWASD()
    2.     {
    3.         v3Cam = Camera.main.transform.position;
    4.     }
    5.  
    6.     float CalculateDirection(float value, float min, float max, float multiplier, Keyboard keyboard)
    7.     {
    8.         if (keyboard.leftShiftKey.isPressed)// Input.GetKey(KeyCode.LeftShift))
    9.             return Mathf.Clamp(value + (multiplier * 2 * Time.deltaTime), min, max);
    10.         else
    11.             return Mathf.Clamp(value + (multiplier * Time.deltaTime), min, max);
    12.     }
    13.  
    14.     private void OnWASD_performed(InputAction.CallbackContext obj)
    15.     {
    16.         var values = obj.ReadValue<Vector2>();
    17.         var keyboard = Keyboard.current;
    18.  
    19.         var tempMaxX = maxX;
    20.         if (BC_Singleton.Instance.SceneGlobals.IsBuildingMenuOpen)
    21.             tempMaxX = maxX + 35;
    22.  
    23.         v3Cam.x = CalculateDirection(v3Cam.x, minX, tempMaxX, values.x * 100, keyboard);
    24.         v3Cam.z = CalculateDirection(v3Cam.z, minZ, maxZ, values.y * 100, keyboard);
    25.  
    26.         Camera.main.transform.position = v3Cam;
    27.     }
    28.  
     
  4. rizu

    rizu

    Joined:
    Oct 8, 2013
    Posts:
    1,080
    I've been testing recent development branch on 2019.3 now but I'm having issues with Logitech G25 wheel. My Thrustmaster TX servo works fine as HID device on new input system but logitech wheel gives me these errors when I try to use "listen" and use the G25 wheel:


    I also tested this on Input System's 0.2.10 preview using 2019.1.8 and there Logitech G25 didn't throw these errors but it didn't recognize any input I put to the wheel (despite it showing the controller on input debugger and recognizing if it was plugged in or out, altho need to mention I couldn't open the input debuggers device view for it).

    edit: I don't really need built-in DirectInput handling from new input system as I'm going to replace it with FFB wheel input lib anyway but I'd love to use the new input systems binding API for it. So this brings me to a new question:

    What is the easiest entry point for 3rd party/custom input? Is there some specific class that would be a good example when implementing this on your own (modifying input system itself for this is not an issue).
     
    Last edited: Jul 17, 2019
  5. ZelekPL

    ZelekPL

    Joined:
    Nov 22, 2018
    Posts:
    1
    I would be interested in this as well. For instance, how would I start to add support for Magic Leap controller bindings?
     
  6. Armetron

    Armetron

    Joined:
    Oct 7, 2016
    Posts:
    12
    Does the input system have a way to distinguish between different gamepads/joysticks

    In the old system when setting the buttons you would specify which joystick to listen to
     
  7. mdsitton

    mdsitton

    Joined:
    Jan 27, 2018
    Posts:
    32
  8. mdsitton

    mdsitton

    Joined:
    Jan 27, 2018
    Posts:
    32
    Yeah I also need to be able to do this. So that would be useful to know.
     
  9. jweidenbach

    jweidenbach

    Joined:
    Dec 29, 2018
    Posts:
    43
    Totally can do. The editor allows you to specify specific devices (if you so choose), and more directly, the PlayerInputManager and PlayerInput components let you establish the link of player controls at runtime (so supporting Xbox or PS4 style 'joining'). I set mine up to join on any button press, and then set up a behaviour that I put on the PlayerInput's prefab. From there, using UnityEvents, it's pretty straightforward to set up control.

    That said, I did have to modify the unity gui module to support working with multiple controllers, but it was a relatively simple mod for my needs.
     
  10. petersvp

    petersvp

    Joined:
    Dec 20, 2013
    Posts:
    41
  11. Rene-Damm

    Rene-Damm

    Unity Technologies

    Joined:
    Sep 15, 2012
    Posts:
    587
    Hey everyone,

    we pushed 0.9.1 yesterday to fix the regression with composites but turns out we ended up with a different regression in it. When you select actions in the action editor, you get exceptions instead of properties in the UI. Sorry about that. Shouldn't have made it out. We will push another package with a fix shortly.
     
  12. Rene-Damm

    Rene-Damm

    Unity Technologies

    Joined:
    Sep 15, 2012
    Posts:
    587
    Easiest way probably is to just create a new "Guitar" layout based on the XInputController layout.

    Code (CSharp):
    1. InputSystem.RegisterLayout(@"
    2.    {
    3.        ""name"" : ""Guitar"",
    4.        ""extend"" : ""XInputController"",
    5.        ""device"" :
    6.        {
    7.            ""interface"" : ""XInput"",
    8.            ""capabilities"" : [
    9.                { ""path"" : ""subType"", ""value"" : 6 }
    10.            ]
    11.        }
    12.    }
    13. ");
    Now you should be able to select "Guitar" as its own type of device under "XInputController" and thus create a separate control scheme for it. (note: only if the code above is executed somewhere in editor code)

    For the record, there's other ways to go about it but they are probably inferior in this case to the solution above.

    Solution B relies on usages. Bindings cannot distinguish devices based on their capabilities which is where the XInput subtype sits (it's part of "InputDevice.description" which bindings are not aware of). However, it can easily be made visible in the form of a "usage" tag.

    Code (CSharp):
    1. InputSystem.onDeviceChange +=
    2.     (device, change) =>
    3.     {
    4.         // If an XInput controller is added that is a guitar,
    5.         // tag it as such.
    6.         if (change == InputDeviceChange.Added &&
    7.             device is XInputController ctrl &&
    8.             ctrl.device == XInputController.SubType.Guitar)
    9.             InputSystem.AddDeviceUsage(device, "Guitar");
    10.     };
    In bindings, the usage tag can be bound to.

    Code (CSharp):
    1. <Gamepad>{Guitar}/buttonSouth
    The system can also be told that this is a common thing for XInputControllers.

    Code (CSharp):
    1. InputSystem.RegisterLayoutOverride(@"
    2.    {
    3.        ""name"" : ""XInputControllerUsages"",
    4.        ""extend"" : ""XInputController"",
    5.        ""commonUsages"" : [ ""Guitar"", ""Wheel"", ""ArcadeStick"" ]
    6.    }
    7. ");
    This should make it bindable from the UI (oops, just noticed we have a regression where you can no longer add devices with specific usages to a control scheme... fixing).
     
    Last edited: Aug 9, 2019
  13. Rene-Damm

    Rene-Damm

    Unity Technologies

    Joined:
    Sep 15, 2012
    Posts:
    587
    So you basically have two options here.

    First one is to bypass the HID fallback. We do this ourselves, too. E.g. DualShockGamepadHID comes in through the same input path as other HIDs but we set up its own layout for it which bypasses the logic in HID that you are getting an exception from. Looking at the code in https://github.com/Unity-Technologi...stem/Plugins/DualShock/DualShockGamepadHID.cs should be helpful in this case. https://github.com/Unity-Technologi...tem/Plugins/DualShock/DualShockSupport.cs#L38 shows how to set up the device matching to override the HID fallback.

    Second option is for when you want to pick up input from a separate API altogether -- which as far as I understand is ultimately what you want to do. The system isn't well documented yet but the gist of it is very simple. There's is a lengthier example here.

    Basically, the steps are
    1. Create a struct that represents the way you want to store and transmit input data for you device.
    2. Put IInputStateTypeInfo on it and give it a custom FourCC tag.
    3. Add fields and annotate the fields with [InputControl] as needed to create the kind of control layout you want for your device.
    4. Create a subclass of InputDevice (or a more specific kind of device, if applicable) and put [InputControlLayout(stateType = typeof(struct_you_created)] on it.
    5. Register the whole thing with the input system. Check the example I linked for a good way to do this during startup such that the editor will also see your device. Important for it to show up in the control picker.
    6. Hook into your API to detect when the device is present and InputSystem.AddDevice<TYourDevice>() it as needed.
    7. Put IInputUpdateCallbackReceiver on your device and in the OnUpdate() method read data out from the API you have and put it in an instance of the struct you created. Then queue the whole thing as an input event with InputSystem.QueueStateEvent().
    This should give you a fully functional device that you can see in the input debugger with all its controls and events coming in. You can hook devices from arbitrary sources into the system like this. It's fairly similar to what InputRemoting does to reflect InputDevices from players in the editor.
     
    Last edited: Aug 9, 2019
  14. Saucyminator

    Saucyminator

    Joined:
    Nov 23, 2015
    Posts:
    19
    Is it possible to bind with modifier keys? Like SHIFT + key, or CTRL + key.
     
  15. Rene-Damm

    Rene-Damm

    Unity Technologies

    Joined:
    Sep 15, 2012
    Posts:
    587
    Not ATM. At least not out of the box. "Chained bindings" are on the list for >1.0.

    One thing that you can do ATM is create a custom composite for that.

    Code (CSharp):
    1. #if UNITY_EDITOR
    2. [InitializeOnLoad]
    3. #endif
    4. public class ButtonWithModifierComposite : InputBindingComposite<float>
    5. {
    6.     [InputControl(layout = "Button")]
    7.     public int modifier;
    8.  
    9.     [InputControl(layout = "Button")]
    10.     public int button;
    11.  
    12.     public override float ReadValue(ref InputBindingCompositeContext context)
    13.     {
    14.         var modifierValue = context.ReadValue<float>(modifier);
    15.         if (modifierValue > 0)
    16.             return context.ReadValue<float>(button);
    17.  
    18.         return default;
    19.     }
    20.  
    21.     static ButtonWithModifierComposite()
    22.     {
    23.         InputSystem.RegisterBindingComposite<ButtonWithModifierComposite();
    24.     }
    25.  
    26.     [RuntimeInitializeOnLoadMethod]
    27.     static void InitInPlayer() {} // Get cctor to run.
    28. }
    29.  
    In the editor, you should now see a "Add Button With Modifier" option show up when clicking the plus icon to add a binding. For example, bind "<Keyboard>/leftCtrl" to "modifier" (if you want both ctrl keys, duplicate the "modifier" binding and bind "<Keyboard>/rightCtrl" to the duplicate) and "<Keyboard>/a" to "button" and the result should be a composite that triggers when both CTRL and A are pressed. This will work with any kind of button. You could, for example, bind a leftTrigger + buttonSouth combination.

    ////EDIT: Replaced it with a better implementation that lets the original key through as is instead of returning 1.
     
    Last edited: Aug 10, 2019
  16. Saucyminator

    Saucyminator

    Joined:
    Nov 23, 2015
    Posts:
    19
    Awesome, thanks!

    Any idea about when chained bindings are to be released? I hope it's not a rude question.
     
  17. Rene-Damm

    Rene-Damm

    Unity Technologies

    Joined:
    Sep 15, 2012
    Posts:
    587
    No ETA at this point. Getting 1.0 out the door is first, then it's time for new plans :)

    BTW, figured the "button + modifier" composites are probably generally useful. Added a PR that adds the composite and a "button + two modifiers" twin directly to the input system.
     
  18. Saucyminator

    Saucyminator

    Joined:
    Nov 23, 2015
    Posts:
    19
    Alright! :)
    The new Input System is very pleasant to work with. Thanks for putting your time into this, I appreciate it!
     
  19. rizu

    rizu

    Joined:
    Oct 8, 2013
    Posts:
    1,080
    @Rene-Damm any chance of getting more info about this:
     
  20. crazy_asian

    crazy_asian

    Joined:
    Jul 14, 2019
    Posts:
    4
    I'm loving how easy it is to setup local multiplayer using the Player Input Manager. I created a top down tank game for my kids and I to play together in no time at all.

    I think I noticed a small bug though, which only seems to happen (so far) when 4 controllers are connected. I'm using Unity 2019.2.0f1, Input System 0.9.2.

    When we first start the play, we all instantiate just fine (see screenshot) using Join Players When Button Is Pressed. But after a few rounds of getting destroyed, eventually, one of the controllers will no longer work. Instead what happens is, the Player Input Manager creates a clone of one of the active players.

    I wrote a Game Manager script to make sure we can't create a clone if we're active in the scene by passing around the player's Gamepad.current.id value, which works great, but now what happens is, well, nothing. The 'dead' controller is no longer being polled by the Player Input Manager until we restart, and everything is fine again for another few rounds.

    I tested in both the Editor and a Windows build version.

    Any clue what might be causing this?

    Thanks!
     

    Attached Files:

  21. Rene-Damm

    Rene-Damm

    Unity Technologies

    Joined:
    Sep 15, 2012
    Posts:
    587
    Here you go. WIP docs. Should contain all the key information at this point. Will get refined further.
     
    rizu likes this.
  22. Rene-Damm

    Rene-Damm

    Unity Technologies

    Joined:
    Sep 15, 2012
    Posts:
    587
    The last part sounds like the actions are disabled. The first part sounds like for some reason the manager is joining a player when it shouldn't.

    Could you go, when trying this in the editor, and pop open the input debugger (Window >> Analysis >> Input Debugger) and do a before and after for me? Each PlayerInput will create one user that shows up under "Users" along with the user's paired devices and actions. Would be curious to see a snapshot of what it looks like before and after the action and how the after-the-fact snapshot compares to what you are expecting.
     
  23. rizu

    rizu

    Joined:
    Oct 8, 2013
    Posts:
    1,080
    Oh, that looks nice. Thank you!

    I noticed that "Device Commands" are not quite there yet, is this going to happen for 1.0 or after? :) My use case for this is force feedback wheel support.
     
    Last edited: Aug 12, 2019
  24. crazy_asian

    crazy_asian

    Joined:
    Jul 14, 2019
    Posts:
    4
    Input Debugger goes blank when I press a button on a controller, but I did take some screenshots before, during, and after just in case that helps.

    First Startup:
    01_Startup.png

    During game play - as soon as I press a button, the Input Debug goes blank, and I am noticing a bunch of errors now with NameAndParameters.cs:
    02_Press_Button.png
    Then, when the problem is happening, I exiting play mode and took another screenshot:
    03_EndedPlayMode.png

    Is there a way for the Input Debug tab stay on while I'm playing? I tried playing with the options but nothing seemed to help.

    I do have some additional information which may be helpful.

    1. This doesn't happen to the same controller, it does appear to be random. This happened to more than 1 controller during a single play session - once I figured out #2 below.

    2. I can 'reactivate' the dead controller by destroying the gameObject that would've originally been cloned. Meaning, when a controller is no longer working, it means one of the other players is seemingly being seen as 2 controllers. To fix the issue, I simply have to destroy that player, and then all is well for a round or two and then it may happen to the same controllers, or different controllers.

    I don't know what that means, but I hope this helps somewhat!

    Thanks,
    Tim
     
  25. crazy_asian

    crazy_asian

    Joined:
    Jul 14, 2019
    Posts:
    4
    Another quick note. I pulled up a debug for each controller and then started the game. When I ran into the problem, I was able to see that the 'dead' controller was still accepting input. I uploaded an animated gif below.

    Thanks!
    dead_controller_works.gif
     
  26. Rene-Damm

    Rene-Damm

    Unity Technologies

    Joined:
    Sep 15, 2012
    Posts:
    587
    It's a relatively small tweak. I expect it for 1.0.

    Sorry about that one :( I messed up a change to the input debugger and it slipped through unnoticed. Fixed in next package. Should be out shortly.

    Yup, this is helpful. I'll do some digging.

    Thank you for checking. Means that at the device level everything is fine. It's really just PlayerInput screwing up.
     
  27. TheLastHylian

    TheLastHylian

    Joined:
    Jan 10, 2013
    Posts:
    9
    This might be a dumb issue, but I have the input system working in the editor, but when I build it no longer works. Should it? Or are preview packages striped out?
     
  28. Rene-Damm

    Rene-Damm

    Unity Technologies

    Joined:
    Sep 15, 2012
    Posts:
    587
    It should work in all players. Which platform are you building for? Can you try connecting the input debugger to the player and see whether it connects? (instructions here) How does "not working" manifest itself in the player?
     
  29. douglassophies

    douglassophies

    Joined:
    Jun 17, 2012
    Posts:
    94
  30. TheLastHylian

    TheLastHylian

    Joined:
    Jan 10, 2013
    Posts:
    9
    I'm building Windows PC, and using a PS4 controller, The Input debugger shows the controller sending Input. It works in the editor I can move my sprite around no issue. I build the scene and I get no response from the stand alone build
     
  31. TheLastHylian

    TheLastHylian

    Joined:
    Jan 10, 2013
    Posts:
    9
    I don't know what fixed it, but I switched from x86 to x86_64 and went in to project settings and changed input system package to only look for the game pad. I also asked me to generate a file on that page. Any way one of those three things fixed it.
     
  32. HeyItsLollie

    HeyItsLollie

    Joined:
    May 16, 2015
    Posts:
    47
    Hopefully this verbose question has a relatively simple answer.
    TLDR version: I'm looking for a way to read a float from any given 2D axis on my gamepad, in a way that'll allow me to use a single generic script on multiple UI game objects — but I need to be able to point to custom HID inputs.

    ---

    I have a very simple script that takes the value of a 2D axis (eg: Left/Right Trigger) as a float, and uses it to display input values through a graphical UI. Thing is, I originally wrote this for Rewired, but I'm currently working with a 3rd-party controller, and a custom HID override which Rewired doesn't currently support. So, I'm trying to re-adapt this script for the new Input System instead.

    For reference, the relevant parts of my original script for Rewired:
    Code (CSharp):
    1.  
    2.     private string button;
    3.     private float axis;
    4.     private float axisNormal;
    5.  
    6.     void Awake() {
    7.         // Get the Rewired Player object for this player and keep it for the duration of the character's lifetime
    8.         player = ReInput.players.GetPlayer(playerId);
    9.  
    10.         // Get the name of the GameObject, use it as the name of the button in GetInput() and ProcessInput()
    11.         button = name;
    12.     }
    13.  
    14.     private void GetInput() {
    15.         axis = player.GetAxis(button); // get input by name or action id
    16.         axisNormal = Mathf.InverseLerp(0f, 1f, axis); // scale axis range to 0f - 1f
    17.     }
    18.  
    My problem lays in GetInput(). This script is made to be generic, so that I can apply it to single button elements (eg: Left Trigger) for multiple controller types, and tweak values as needed. Rewired allows me to use "GetAxis()" to grab the value of any axis OR button as a float — in this case, I've been using the game object's name as a string, and matching it to whatever joystick mapping or action that I've set up. I can technically pass a face button as an axis if I wanted to, and it'll give me constant 0f and 1f values just fine.

    The issue I've been running into here is that (as far as I can tell from the WIP documentation) the new Input System seems to expect specific names before it'll allow you to grab a value. Instead of being able to use a generic value like "button", Input System seems to expect specific names for every element, something along the lines of "Gamepad.current.leftTrigger.ReadValue()". My controller has twelve 2D axes in total (it's a PS2 DualShock with pressure sensitivity in every button), so I want to avoid making separate scripts for every single button.

    What do I need to change in order to make this work with the new Input System?
     
    Last edited: Aug 16, 2019
  33. frarf

    frarf

    Joined:
    Nov 23, 2017
    Posts:
    16
    I believe that you can access InputMap actions by string name rather than API name. eg:
    master[button].ReadValue<float>()


    This is in the docs, unless I'm misinterpreting the problem.
     
  34. HeyItsLollie

    HeyItsLollie

    Joined:
    May 16, 2015
    Posts:
    47
    Is that in the WIP docs on Github, or somewhere else? I'm having trouble finding it.

    Either way, I must be missing something. Unity Console throws me this error:
    'InputControl' does not contain a definition for 'ReadValue' and no accessible extension method 'ReadValue' accepting a first argument of type 'InputControl' could be found


    For what it's worth, my script is using "UnityEngine.InputSystem" and "UnityEngine.InputSystem.Controls".
     
  35. YoyoMario

    YoyoMario

    Joined:
    Apr 8, 2013
    Posts:
    11
    Maybe it's been posted here but I didn't find anybody asking it.
    With the new InputSystemManager, how can I check for controller axis runtime?
    My simulation will be handling 100+ different radio system controls, InputSystemManager, offers me in the inspector to link my own ("Taranis") radio and it probably wont work for other radios of different brand, so I would like to give users to setup their controllers on runtime.

    Is it possible to achieve that? To use the "Listen" function from the inspector when assigning axis or buttons to a map?

    Best regards,
    Mario
     
  36. terids

    terids

    Joined:
    Sep 23, 2017
    Posts:
    3
    My device is listed under "unsupported". Is there any way to add it to make it supported, or am I just out of luck?
     
  37. Rene-Damm

    Rene-Damm

    Unity Technologies

    Joined:
    Sep 15, 2012
    Posts:
    587
    My suggestion would be to put a PlayerInput next to your component (the one you've pasted the snippet of). That component itself is sort of an equivalent of a player ID in Rewired. I.e. by virtue of being instantiated, it represents a player.

    To connect PlayerInput to your .inputactions, assign them to PlayerInput's "Actions" property.

    In your script, you can do

    Code (CSharp):
    1. private InputAction button;
    2.     private float axisNormal;
    3.  
    4.     // Link PlayerInput here from the inspector or look it up in Awake() using GetComponent
    5.     // or GetComponentInChildren.
    6.     public PlayerInput input;
    7.  
    8.     void Awake() {
    9.         // Look up action by using the GameObject's name as the action name
    10.         button = input.actions[name];
    11.     }
    12.  
    13.     private void GetInput() {
    14.         // All buttons are [0..1] floats.
    15.         axisNormal = button.ReadValue<float>();
    16.     }
    17.  
    Working with raw HIDs in .inputactions is a bit quirky ATM but doable.

    One way to do it, is to connect your HID. If it's recognized, it should show up under "Joystick" in the control picker with a weird-looking label such as "HID::Blablabla" listed under "More Specific Joysticks". When you select it you should see the buttons and axes on the device with generic names such as "button1" etc. that you can bind to. The downside is that these bindings will ONLY work with that specific HID. Which in your case, may be just fine.

    To make the bindings work more universally ATM does require some manual massaging of the binding strings by switching the "Path" property to text mode via the little "T" button on the right side. This way you can, for example, bind to the third button on any joystick.

    Code (CSharp):
    1. // Third button any joystick.
    2. <Joystick>/button2
     
    HeyItsLollie likes this.
  38. Rene-Damm

    Rene-Damm

    Unity Technologies

    Joined:
    Sep 15, 2012
    Posts:
    587
    "Listen" in the control picker is entirely based on InputActionRebindingExtensions.RebindingOperation which is a public API. See here.

    To easiest way to initiate an interactive rebind on an action, is to call PerformInteractiveRebinding(). The resulting object has copious options for customizing its workings. By default, it will non-destructively apply an override to bindings.

    Code (CSharp):
    1. var rebind = myControls.gameplay.fire.PerformInteractiveRebinding();
    2. // Example: rebind only binding from gamepad control scheme.
    3. rebind.WithBindingGroup("Gamepad");
    4. rebind.Start();
     
  39. Rene-Damm

    Rene-Damm

    Unity Technologies

    Joined:
    Sep 15, 2012
    Posts:
    587
    Depends :)

    Just to make sure, one reason devices end up there as they aren't compatible with what's chosen as "Supported Devices" in the "Input System Package" project settings. If that is the case, it can be as simple as adding the device as supported.

    If that's not the case, then from the fact it shows up "Unsupported Devices" we know that at least Unity is seeing the device and probably knows how to talk to it. On Windows and Mac, you're probably looking at a HID. It ending up under "Unsupported Devices" means that it either has a HID usage we don't support by default or that we couldn't find any usable controls on the device (there's plenty HIDs, for example, where everything on the device is marked VendorDefined).

    ATM there's no good way to find which is the case using the Input Debugger. There's a change coming that will allow you to dump the device descriptor to the clipboard but it's not yet in 0.9.3. ATM you will have to use a 3rd-party HID/USB dumper tool or simply know the device.

    If it's a case of the HID usage of the device not being supported out-of-the-box (we currently pick up GenericDesktop.Joystick, GenericDesktop.Gamepad, and GenericDesktop.MultiAxisController), you can hook into HIDSupport.shouldCreateHID and manually "greenlight" your HID.

    If it's a case of the HID fallback not being able to work with the controls present on the device, you will have to build your own device layout for the device to work with the input system. Doing so isn't super tricky but does require some custom scripting. There's documentation here.
     
  40. HeyItsLollie

    HeyItsLollie

    Joined:
    May 16, 2015
    Posts:
    47
    This did exactly what I needed, thank you!

    Unfortunately I've run into another issue - I think I'm failing to initialize my HID controller correctly? I can see the controller (and my custom HID override) in the Input Debugger, and I can use the "Listen" function to bind it to Input Actions. But when I'm in Play mode, Unity won't pair this specific controller to User #0. Other controllers pair up just fine - I've tried unplugging them just in case, but no luck.

    I've followed the HID documentation, although I haven't added the "[RuntimeInitializeOnLoad]" lines from Step #3 to anything.
    Code (csharp):
    1. using UnityEngine;
    2. using UnityEditor;
    3. using System.Runtime.InteropServices;
    4. using UnityEngine.InputSystem.Layouts;
    5. using UnityEngine.InputSystem.LowLevel;
    6. using UnityEngine.InputSystem.Utilities;
    7.  
    8. namespace UnityEngine.InputSystem.LowLevel
    9. {
    10.     [StructLayout(LayoutKind.Explicit, Size = 20)]
    11.  
    12.     [...] // 83 lines of definitions that don't need to be quoted here
    13.     // Picking it back up at Line #95
    14.  
    15.     [InputControlLayout(stateType = typeof(DualShock2HIDInputReport))]
    16.     #if UNITY_EDITOR
    17.     [InitializeOnLoad] // Make sure static constructor is called during startup.
    18.     #endif
    19.     public class DualShock2GamepadHID : Gamepad
    20.     {
    21.     static DualShock2GamepadHID()
    22.         {
    23.         InputSystem.RegisterLayout<DualShock2GamepadHID>(
    24.             matches: new InputDeviceMatcher()
    25.                 .WithInterface("HID")
    26.                 .WithProduct("MUSIA PS2 controller"));
    27.         }
    28.     }
    29. }
     
  41. Rene-Damm

    Rene-Damm

    Unity Technologies

    Joined:
    Sep 15, 2012
    Posts:
    587
    Can you email me (rene AT unity3d.com) that file above in full plus your .inputactions file? Probably the quickest way to debug this.
     
  42. HeyItsLollie

    HeyItsLollie

    Joined:
    May 16, 2015
    Posts:
    47
    Just sent, thank you for checking it out!

    I forgot to mention, Unity does pick up the HID controller when I'm not using a custom HID override. It feels like user error on my part, I just can't see where that error is.
     
  43. rizu

    rizu

    Joined:
    Oct 8, 2013
    Posts:
    1,080
    This still happens on 0.9.3-preview, it appears that the HID structure is hitting some not implemented exception, is this something I could try to solve with custom HID setup or is it more structural issue on Unity's new input system?
     
  44. Rene-Damm

    Rene-Damm

    Unity Technologies

    Joined:
    Sep 15, 2012
    Posts:
    587
    This could be solved with a custom HID layout but a HID hitting that exception seems very suspicious to me. A sizeof>=32bit field straddling an int boundary strikes me as an extremely odd thing to encounter with a HID. I'm guessing that this is actually the HID fallback messing something up.

    Would you mind setting a breakpoint where it generates the exception and then check a couple frames up which input control triggers it? Also, if you could, would you check the "HID Descriptor" window to track down the control and post a screenshot of the control?

    (Sorry for the awkward debugging; working on something that will at least somewhat help tracking down HID issues like this)
     
  45. Rene-Damm

    Rene-Damm

    Unity Technologies

    Joined:
    Sep 15, 2012
    Posts:
    587
    Thank you for the files.

    I see some problems in the file that are likely the cause of what you are seeing. Some of the problems are likely produced by a quirk the action editor still has.

    The first problem is that the control scheme you have for the controller does this:

    Code (CSharp):
    1. "controlSchemes": [
    2.         {
    3.             "name": "PS2",
    4.             "basedOn": "",
    5.             "bindingGroup": "PS2",
    6.             "devices": []    <--- empty
    7.         },
    PlayerInput will base its device assignments on what it finds as the device requirements on individual control schemes. Adding your DualShock2GamepadHID device as a requirement here should solve the problem with PlayerInput not picking up your device.

    However, there's another problem in that "bindingGroup" of the control scheme doesn't match the name of the group used in the bindings. The scheme uses "PS2" whereas the bindings use "PS2Scheme". This is likely the result of editing/renaming the control scheme setup. ATM the action editor can easily be fooled into messing up the binding setup when renaming and deleting and re-creating control schemes. Have it on my TOFIX list :)
     
    HeyItsLollie likes this.
  46. rizu

    rizu

    Joined:
    Oct 8, 2013
    Posts:
    1,080
    What you mean by couple frames up in this context? like just the callstack to that point? You can see the same callstack on the screenshot below which lists some controls.

    I can't even open the Input Debuggers device dialog, if I double click the Logitech G25's device, I get this:
     
  47. Rene-Damm

    Rene-Damm

    Unity Technologies

    Joined:
    Sep 15, 2012
    Posts:
    587
    Ugh, I see. Sorry about that.

    There's a change I intend to land in 0.9.4 that should make debugging this much simpler. To debug this on my side, I'll need the device description which with that change can be gotten to in two clicks. If it's okay, let's wait for 0.9.4 to hit (I expect that to happen within a week) and then let's debug this further.
     
  48. rizu

    rizu

    Joined:
    Oct 8, 2013
    Posts:
    1,080
    I grabbed the PR to get the device description for Logitech G25.
     
    Rene-Damm likes this.
  49. HeyItsLollie

    HeyItsLollie

    Joined:
    May 16, 2015
    Posts:
    47
    This was the thing! God, of course it'd be a simple "gotcha", lol. Thank you so much.

    One last quick question: Do I need to add anything to the HID override to get it working in a build? It's working in editor, but doesn't appear to be doing anything in a stand-alone player.
     
    Last edited: Aug 21, 2019 at 5:13 AM
  50. Rene-Damm

    Rene-Damm

    Unity Technologies

    Joined:
    Sep 15, 2012
    Posts:
    587
    That's the [RuntimeInitializeOnLoadMethod] bit you mentioned before.
     
    HeyItsLollie likes this.