Search Unity

Extensible Input Manager

Discussion in 'Assets and Asset Store' started by Gargore, Feb 8, 2014.

  1. Gargore

    Gargore

    Joined:
    Jun 21, 2013
    Posts:
    83
    Now published: new thread is: http://forum.unity3d.com/threads/232712-RELEASED-Extensible-Input-Manager

    We were looking a time ago for an easily Extensible Input Manager for our game, we know that there are some out there, but none of that were fulfilling all our requisites... so... we decided to make one on our own, so we are working in it! and it is almost finished! We thought that perhaps it could be interesting for you if we publish the spec list:
    • The most important, it should be extensible: user can write it's own device interfaces by implementing inherit the base device interface object. We needed that things like arduino pads or wheels, or xbox 360 full supported driver were fully and transparently integrated in the manager as native: it's done.
    • Integrate a override that replaces completely and transparently the Input object without needed to change the whole code of the already existent code: done, we made that only adding one header to the file replaces completely and transparently the Input object by our own manager.
    • Needed to support for complete single-touch/multi-touch and accelerometer virtual axes, fully embeded, working exactly like the native ones.
    • Integrate a table like the native Input Manager for our game designers to change the settings without changing the source code of the project.
    • Game Controls Menu allows changing settings while in runtime: methods for doing so were added, and for debugging and demo purporses a embedable customizable menu was added. It allows changing not only button assignements, also it can detect axes changes and assign them.
    • Integrated also a multi-touch emulator. Tired of waiting while the game image is uploaded to your handheld device? Now you can make faster debugging from the unity editor. Automatic detects unity dev environment and sets-up replacing multitouch default implementation, adding some draggable items to simulate fingers.
    • Finally we needed to support and integrate special inputs: absolute axes (not the limited [-1, 1] ones), 2D and 3D axes and selectors, screen pointers, 3D pointers. We added additional code for supporting them.
    We have planned to release three flavours, if we can:
    • free: the library + code that allows you to implement and test your own device interfaces (including two examples of overrided button and axis).
    • computer bundle: the library + prebuilt device interfaces for computer (mouse virtual joystick, mouse look, axis mixer, button mixer) + transparent Input override + Input manager Table + Run-time Game menu.
    • mobile bundle: includes computer bundle + additional Device Interfaces for handhelds (multi-touch and accelerometer virtual joysticks, code for reading device location, gps and orientation) + drag&drop prebuilt virtual joysticks.
    Hope that you like it!

    $screenshot2.png

    $screenshot3.png

    $screenshot1.png
     
    Last edited: Mar 7, 2014
  2. Gargore

    Gargore

    Joined:
    Jun 21, 2013
    Posts:
    83
    We have sent the first version to publication.
     
  3. duencil

    duencil

    Joined:
    Dec 17, 2012
    Posts:
    91
    That its open to extension sounds like a good plan.
    Whats the planned pricing?

    I wrote a native DirectInput plugin to improve gamepad and joystick compatibility under windows. It would be nice to integrate that into a generic framework like you propose, so input response game code can be more multiplatform.
     
  4. Gargore

    Gargore

    Joined:
    Jun 21, 2013
    Posts:
    83
    During the first weeks it will cost $5 (computer bundle) and $15 (mobile bundle, now we changed the name to handheld bundle).

    Handheld bundle has been submitted already to the Asset Store and will be public in the following days.
     
  5. Gargore

    Gargore

    Joined:
    Jun 21, 2013
    Posts:
    83
    Here is an example of how to integrate your joystick inside the Extensible Input Manager (based on what I saw on http://forum.unity3d.com/threads/173147-Poorly-supported-joysticks).

    Code (csharp):
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4. public class VirtualInterfaceExample: GInputInterfaceBase, GInputInterface {
    5.    
    6.     new public bool implementsGetAxis(string inputName) {
    7.         return true;
    8.     }
    9.    
    10.     new public float GetAxis(string inputName) {
    11.         return DxInputManager.Instance.GetValue(inputName);
    12.     }
    13. }
    I think that is all. If you need some initialization code or maybe timed code, or others (keep in mind that GetAxis will be called each time the user reads the axis value), there are additional methods that you can define, for example:
    • configuration: you can implement implementsInputConfig and InputConfig for receiving configuration queries. We provide a helper class for managing configurations.
    • periodic calls: you can implement implementsInputUpdate and InputUpdate for receiving periodic calls, for example if you need to poll something apart from the calls to GetAxis (which are not periodic).
    • register and unregister notification: you can implement RegisterInstance or UnregisterInstance to be called each time the user creates an axis / button / other kind of input based on your device.
    Also, you can use other bases instead of GInputInterfaceBased for getting additional already made features.

    Finally we are working in integrating additional elements like force feedback or vectorial input/output for creating richer devices.
     
  6. duencil

    duencil

    Joined:
    Dec 17, 2012
    Posts:
    91
    That seems pretty clear, though at first glance I'm not quite sure if the VirtualInterface here would be an individual device, or a means of accessing devices, like DirectInput in my case. I suspect the latter, but then is it possible for the interface to report the number of connected devices detected, and for each device to report the inputNames they support, and whether they are buttons, axes, etc, so the app can discover the features of the input devices connected?
     
  7. Gargore

    Gargore

    Joined:
    Jun 21, 2013
    Posts:
    83
    VirtualInterfaceExample (you can call as you want) can act like a individual interface and axis or like several. Anyway your class will be instanced one time per axis.

    For making the binding user will use a table provided (see the third sshot of the first post) or also can bind by code (as the table does internally).

    An example of how binding by code could be:

    Code (csharp):
    1.  
    2.         GInput.registerInterface("Horizontal", new VirtualInterfaceExample());
    3.         GInput.configInterface("Horizontal", "source=X Axis;debug=true");
    4.         GInput.registerInterface("Vertical", new VirtualInterfaceExample());
    5.         GInput.configInterface("Vertical", "source=Y Axis;debug=true");
    6.  
    or, if you need, for example a parameter with the number of the joystick or any id you can use:

    Code (csharp):
    1.  
    2.         GInput.registerInterface("Horizontal", new VirtualInterfaceExample());
    3.         GInput.configInterface("Horizontal", "source=X Axis;joystick=3;debug=true");
    4.         GInput.registerInterface("Vertical", new VirtualInterfaceExample());
    5.         GInput.configInterface("Vertical", "source=Y Axis;joystick=3;debug=true");
    6.  
    The parameters source and joystick are passed to VirtualInterfaceExample and can be read easily with GInputHelper class:

    Code (csharp):
    1.  
    2.     public class VirtualInterfaceExample: GInputInterfaceBase, GInputInterface {
    3.         [...]
    4.         private string configString = "";
    5.         private string source = "X Axis"; // default value
    6.         private int joystick = 1; // default value
    7.         private bool debug = false;
    8.  
    9.         new public bool implementsInputConfig(string inputName) {
    10.             return true;
    11.         }
    12.  
    13.         new public string InputConfig(string inputName, string newConfigString) {
    14.             if (newConfigString != null) {
    15.                 source = GInputHelper.configGetValueString(newConfigString, "source", source);
    16.                 joystick = GInputHelper.configGetValueInt(newConfigString, "joystick", joystick);
    17.                 configString = newConfigString;
    18.             }
    19.             return configString;
    20.         }
    21.         [...]
    22.         new public float GetAxis(string inputName) {
    23.             return DxInputManager.Instance.GetValue(source, joystickNumber);
    24.         }
    25.         [...]
    26.     }
    27.  
    Finally you can use Input.GetAxis("Horizontal") and Input.GetAxis("Vertical") as usual because now VirtualInterfaceExample will handle those axes.
     
  8. duencil

    duencil

    Joined:
    Dec 17, 2012
    Posts:
    91
    This feature that the Game Controls Menu can detect axes changes and assign them is important to me. I assume this means device interfaces respond to added or removed devices and enumerate their axes/buttons. So how would my extension report the axes/buttons of the devices it provides an interface for? This was what I was trying to ask before.
     
  9. Gargore

    Gargore

    Joined:
    Jun 21, 2013
    Posts:
    83
    Yes, the scanner searches a complete list of inputs, not only keys, also sets of axes, and directions. There are priorities also: for example, if you press left ctrl key with the default unity settings we will detect the unity fire1 button instead of the left ctrl key. You can change the priorities in the Input Manager scanner properties. Also, for axes scanning, we can detect directions, not only axes, so user can invert intuively the axis by selecting look left action and press the joystick axis to the right.

    If you want, you can contact us in uas@gargore.com and tell us as many feedback as you want: we are collecting it so library is improved to the users needings :).
     
  10. duencil

    duencil

    Joined:
    Dec 17, 2012
    Posts:
    91
    Oh I see, this scanner is for detecting currently pressed pressed buttons or axes, so the user can assign them. This is a very useful feature -- its not what I understood before but very handy. Anyway, just to finish the point I was failing to get across, as something to put into your list of suggestions for future improvements, it would be nice if the developer didnt have to have that complete list of inputs, so that a user can plug in a device with new axes names or buttons that the developer didnt anticipate, and the device interface can report them to the scanner as being available (or add them to that complete list of inputs) automatically so they become available for mapping to actions.

    Thanks for the email contact - I realize this is an announcement thread and I'll try not to clutter it up more with questions on these particulars.
     
  11. Gargore

    Gargore

    Joined:
    Jun 21, 2013
    Posts:
    83
  12. Ecocide

    Ecocide

    Joined:
    Aug 4, 2011
    Posts:
    293
    Hi Gargore,

    great contribution! This is what I need. There seems to be no other input manager where you can actually specify the joystick number by code.

    I currently use Input.GetJoystickNames() : string[] in order to find out the joystick names and its numbers, but I never had a chance to actually assign a number to a specific option.
     
  13. Gargore

    Gargore

    Joined:
    Jun 21, 2013
    Posts:
    83
    Hope to hear so. If you have any sugestion, please feel free to tell it us :)
     
  14. Ecocide

    Ecocide

    Joined:
    Aug 4, 2011
    Posts:
    293
    Hey Gargore,

    I recently purchased your asset, but I can't get it to work properly.
    I added
    Code (csharp):
    1.  
    2.  
    3.     using Input = com.gargore.InputManager.Override.Input;
    4.  
    in the script file where I'm using Input.GetAxisRaw("Horizontal");

    Then I run these lines in another script:
    Code (csharp):
    1.  
    2.     GInput.registerInterface("Horizontal", new GInputInterfaceExample());
    3.     GInput.configInterface("Horizontal", "source=Axis 0;joystick=2;debug=true");
    4.  
    But apparently it's not changing the input to those settings.

    Is there anything else I have to do?
     
  15. Gargore

    Gargore

    Joined:
    Jun 21, 2013
    Posts:
    83
    There is separate implementations for GetAxis and GetAxisRaw. But if you are using the computer or handheld bundles both GetAxis and GetAxisRaw fallback to the twisted implementation so it should work.

    Maybe there is some initialization in your example that is not being runned. Can you test it? I created this example script and it works as spected:
    Code (csharp):
    1.  
    2. using UnityEngine;
    3. using System.Collections;
    4. using com.gargore.InputManager;
    5. using Input = com.gargore.InputManager.Override.Input;
    6.  
    7. public class testGetAxisRaw : MonoBehaviour {
    8.  
    9.     // Use this for initialization
    10.     void Start () {
    11.         GInput.registerInterface("Horizontal", new GInputInterfaceExample());
    12.         GInput.configInterface("Horizontal", "source=Axis 0;joystick=2;debug=true");
    13.     }
    14.    
    15.     // Update is called once per frame
    16.     void Update () {
    17.         Input.GetAxisRaw("Horizontal");
    18.     }
    19. }
    20.  
    Console outputs continously:
    Code (csharp):
    1.  
    2. GInputInterfaceAxis: Horizontal: received and bypass value 0
    3. UnityEngine.Debug:Log(Object)
    4. com.gargore.InputManager.GInputInterfaceExample:GetAxis(String) (at Assets/Plugins/Extensible Input Manager/Scripts/Interfaces/GInputInterfaceExample.cs:42)
    5. com.gargore.InputManager.GInput:GetAxisRaw(String) (at Assets/Plugins/Extensible Input Manager/Scripts/GInput.cs:249)
    6. testGetAxisRaw:Update() (at Assets/testGetAxisRaw.cs:16)
    7.  
    changing the value from 0 to 1 depending on the movement of Axis 0.
     
  16. Ecocide

    Ecocide

    Joined:
    Aug 4, 2011
    Posts:
    293
    Hm, no it's still not working. As soon as I add the line
    Code (csharp):
    1. using Input = com.gargore.InputManager.Override.Input;
    it stops working. Also tried Input.GetAxis and GInput.GetAxis ...

    I really don't know what I'm doing wrong here :-(

    In the editor I am getting this error:
    Code (csharp):
    1. UnityException: Input Axis 0 is not setup.
    2.  To change the input settings use: Edit -> Project Settings -> Input
    and it directs me to line 41 in the GInputInterfaceExample script.

    After analyzing your code I changed:
    Code (csharp):
    1.  GInput.configInterface("Horizontal", "source=Axis 0;joystick=2;debug=true");
    to
    Code (csharp):
    1.  GInput.configInterface("Horizontal", "source=Horizontal;joystick=2;debug=true");
    and after setting Horizontal manually in the input manager it is working again.

    There must be something wrong in your implementation I guess, because in line 41
    Code (csharp):
    1.             float retv = UnityEngine.Input.GetAxis(source);
    you try to use Unitys GetAxis using a string like "Axis 0" which is definitely not working because here you can only use strings that are definied in the input manager
     
    Last edited: Mar 10, 2014
  17. Gargore

    Gargore

    Joined:
    Jun 21, 2013
    Posts:
    83
    I know whats happening now.

    The reason is GInputInterfaceExample reads Axis 0 from unity standard system, because you set source=Axis 0, that's it's way of working of the example device: reads from unity standard input system the axis set in config source, allows you to make a transformation or a log and send the result to the library.

    You need to define Axis 0 in the standard Unity Input Manager or use other device than GInputInterfaceExample, or modify it's code.

    In addition Extensible Input Manager Input.GetAxis tries first to find a axis definition in the library table, but if it does not found it, it fallback to the standard unity axis table in a effort of maintaining transparent usage.
     
  18. Ecocide

    Ecocide

    Joined:
    Aug 4, 2011
    Posts:
    293
    Okay, thank you. I don't really know what to do now. All I want is to set the joystick number and axis of (for example) "Horizontal" by script. Is this possible? If yes, could you please explain?
     
  19. Gargore

    Gargore

    Joined:
    Jun 21, 2013
    Posts:
    83
    You can do it by several ways, but currently the most recomended way is using the infrastructure provided by unity, as it is plattform independent and most portable solution. You can also use a driver like the one by duencil. Anyway, with the portable solution:

    Step 1.
    You must configure as usual before using extensible input manager some different axes for each joystick in the standard's Unity Input Manager table. For example create some axes and name as: joy1axis1, joy1axis2, ..., joy2axis1, ... and configure them to bind to the respective joysticks and axes (this will be provided in a zip compressed project folder in the next release as part of the Unity 3.5 and 4.x compatibility package).

    Step 2.
    Now, once the standard unity axes have been created you can bind them to the horizontal axis in runtime by using this code, for example:

    Code (csharp):
    1.  
    2. GInput.registerInterface("Horizontal", new GInputInterfaceAxis());
    3. GInput.configInterface("Horizontal", "source=joy1axis2"); // you can write here any unity axis you want instead of joy1axis2
    4.  
    Or by using the computer or handheld bundle provided extensible input manager table.

    Finally, if you want to reconfigure the horizontal axis to use a different source simply run the following, for example:

    Code (csharp):
    1.  
    2. GInput.configInterface("Horizontal", "source=joy3axis2"); // you can write here any unity axis you want instead of joy3axis2
    3.  
     
  20. Ecocide

    Ecocide

    Joined:
    Aug 4, 2011
    Posts:
    293
    Thank you so much!
    I know that this is not the ideal way when it comes to different plattforms etc but in my current project it has to be completely fixed and I'm pretty sure that's the best solution.
     
  21. Ecocide

    Ecocide

    Joined:
    Aug 4, 2011
    Posts:
    293
    Ok everything is working fine. My next question: Is it possible to use for example Input.GetButton("Left Turn Signal") and let it automatically use Input.GetKey("joystick 2 button 1")? Do I have to write my own interface for that?

    The intention is again to map that virtual "GetButton("Left Turn Signal")" to an actual joystick x button y.
     
  22. Gargore

    Gargore

    Joined:
    Jun 21, 2013
    Posts:
    83
    Joystick buttons are preassigned and accesible without neededing of creating standard unity input manager entries (as described in https://docs.unity3d.com/Documentation/Manual/Input.html in the button names section). You can use GInputInterfaceButton and set a source of type key:

    Code (csharp):
    1.  
    2. GInput.registerInterface("Left Turn Signal", new GInputInterfaceButton());
    3. GInput.configInterface("Left Turn Signal", "source=key:joystick 2 button 1");
    4.  
    The key: prefix forces GInputInterfaceButton to access the value using always standard unity Input.GetKey method. Those two lines are enought.
     
  23. Ecocide

    Ecocide

    Joined:
    Aug 4, 2011
    Posts:
    293
    Great, thanks again!
    Seems like another must-have asset to use, hehe :D
     
  24. Ecocide

    Ecocide

    Joined:
    Aug 4, 2011
    Posts:
    293
    One very last question: Is it possible to invert an axis like the setting in the Unity Input Manager?
     
  25. Gargore

    Gargore

    Joined:
    Jun 21, 2013
    Posts:
    83
    Of course!

    Even the config menu is able to detect invert inputs.

    You simply must write in the config string:

    source=-joy3axis2

    or alternatively you can write:

    source=joy3axis2;inverted=true

    You can also specify input and output clamping, filtering, sensivity and clamping types. We are working in the website, including a full manual with every options. If you have the handheld version the virtual joysticks and accelerometer joystick also have different modes, for example the acelerometer can work in either 3 modes: center fixed, slow autocenter or clamping.

    Also we need to include yet some components in the library. The idea is make prefabs with vritual joysticks, everything included, ready for read with Input.GetAxis.
     
  26. Ecocide

    Ecocide

    Joined:
    Aug 4, 2011
    Posts:
    293
    Hey Gargore,

    could you please reassure that this is working? It does not work and I cant find any keyword like "invert" in any of your scripts.

    Code (csharp):
    1.  
    2. GInput.registerInterface("Throttle", new GInputInterfaceAxis());
    3. GInput.configInterface("Throttle", "source=joy2axis1;inverted=true;joystick=2;debug=false";);
    4.  
    Chaning the inverted value does not do anything. As soon as I change it directly in the Input Manager it works.
     
  27. Gargore

    Gargore

    Joined:
    Jun 21, 2013
    Posts:
    83
    Check at GInputInterfaceAxis.cs at line 90.

    If you invert in the input manager it will work; remember that if you invert again in the extensible input manager the double inversion makes invert cancelled.

    The joystick=2 parameter is unused by GInputInterfaceAxis and it will be ignored. Maybe you should not use it.

    The debug=false or debug=true is not used by GInputInterfaceAxis (only in GInputInterfaceExample), so it will be ignored.

    Finally instead of using inverted=true, it is better that you use the simplified syntax source=-joy2axis1 as it is the default.
     
  28. Ecocide

    Ecocide

    Joined:
    Aug 4, 2011
    Posts:
    293
    Okay but this would mean creating another pack of elements in the Input Manager like you said in this post:

    Am I right?
     
  29. Gargore

    Gargore

    Joined:
    Jun 21, 2013
    Posts:
    83
    No, no, the simplified syntax source=-joy2axis1 will use joy2axis1. You don't need to create -joy2axis1, indeed you must not use neither - or * in the axis name, because they are used by a aricmethic parser embeded in the axis and button interfaces.

    You can also use things like source=-1.4*joy2axis1 if you want to specify sensivities.
     
  30. Ecocide

    Ecocide

    Joined:
    Aug 4, 2011
    Posts:
    293
    Ahh okay, when I first tested this using a minus I was refering to the wrong interface.
    Now it works :)