- Home /
How do I add a value to anywhere Input.GetAxis("Horizontal") is called?
I'm working on the Unity portion of an immersive, site-specific escape-room style experience.
I will be receiving input from various physical devices which will send signals via UDP. So for example, we'll have a steering wheel that could send an 'a' character when the wheel is turned hard left, 's' when turned slightly left, 'f' when turned slight right, and 'g' when turned hard right.
I'd like to be able to use the BaseInputModule.inputOverride() (or a better-documented EventSystem solution?) to have those signals be added to Input.GetAxis("Horizontal"), so that I can map the 'a' UDP signal to add a value of -1 to that axis value, 's' to add -0.5 to the axis, 'f' to add 0.5, and g to add 1.
I'd like them to add to those axis values so that I can continue to use the StandardInputModule to test the level design from my keyboard, but when the keyboard is left alone and the UDP signals are coming in, they'll take over without needing code switched out.
Any ideas or example code of using BaseInputModule.inputOverride(), extensions, or otherwise extending or wrapping Input to accomplish something like this?
Thanks for any advice here.
Answer by JVene · Aug 08, 2018 at 05:58 PM
See if the input manager is sufficient for what you require. I doubt that, but you could have a look.
From your post, we can't tell what OS you're using. The input system in Unity is intended to deal with platform dependent input API's, providing a platform independent means of gaining input. It is largely configured internally toward that purpose, where the input manager dialog allows "gross level" changes, usually selecting which among several attached devices provides a particular input recognized by the "keys" given, like "Horizontal" to the GetAxis call.
However, your description hints at a potentially better solution. I assume by UDP you mean you're getting packets of data via a TCP/IP configured connection. There is, actually, a common theme among a variety of applications doing this for multiplayer gaming. While your application is not that type, the underlying technical points are nearly identical.
What I suggest is that you view this from the same object oriented programming perspective which gave rise to the Input class (and system) in Unity, but since I sense Unity's input system isn't geared to your particular, unique, requirements you should implement your own. This is the essence of object oriented design and programming.
The whole reason Input works as it does is because all code uses calls to methods or properties of the Input class to gain input information during the time slice of Update or FixedUpdate functions, even though the input comes from different times (key ups and downs, for example, don't happen in sync with the Update function).
If you create a class which represents your input interests, you can wrap all input interpretations in the way you need, which can still consume services from the Unity Input class, or from your own unpacking of packet information. It would end up being the same as if you could rewrite the Unity input system to suit your needs, without having access to their code for doing that. This, too, is part of the object oriented paradigm, the notion of wrapping concepts into a class. Unity's Input class already wraps very different input sources into a single interface. An interface class like I'm proposing extends that very same design.
First, create a class that will represent your version on Unity's Input class. This is the basic "wrapper" style class, where, at first, during the initial development phase, you're merely forwarding calls to your class to Unity's Input. Many of the functions you call are static methods of Input, so you create similar static methods which merely forward calls to Unity.
Then, your application is merely edited to change Input. calls to your class. Let's say you call your class ExInput. You could fashion ExInput so that throughout your code, you merely add Ex in front of all Input calls. You've now "absorbed" Input into your class, but you can now interrupt anything you required.
Now, consider the ExInput method GetAxis, when the key is "Horizontal". Instead of forwarding that to Unity's Input, you unpack data coming from UDP to return what you require.
This implies that you'll probably have a thread running which accepts the appropriate UDP data, unpacks it and stores the results in ExInput static member variables representing the incoming data, which is loosely the description of what Unity's Input system is doing from a wide variety of input sources. With this model, you have complete control without having to write multiple input checks (using Input for some things, ExInput for others).
Trust the compiler to realize some of these "wrapper" functions do nothing, and elide the multiple calls implied. However, you may prefer the simplicity of only replacing GetAxis, and that's a reasonable choice (which is to say you'd use ExInput only for GetAxis, and Input for all other I/O). My underlying theme is that I assume re-configuring Unity's Input system isn't going to get what you need, and you really must interpret the packet data to provide that as information to your input requirements. You likely need a thread to serve the incoming UDP packet reception and unpacking, forwarding that to a class with static methods used to retrieve the interpreted results.
I agree a 100%, but I'm actually a bit curious on how to use BaseInput$$anonymous$$odule.inputOverride, I couldn't find any meaningful documentation on it so far.
The design I see suggests the BaseInput class is the intended position for modification or extension of the input system (the docs even suggest one could provide 'fake' input, which would also mean alternative input). That's what inputOverride expects, a new BaseInput class that provides input.
As I consider your situation, then exa$$anonymous$$e the layout of the input system class hierarchy, it appears that creating a BaseInput derivative, then handing that to 'inputOverride' is the intended method for changing the input system.
$$anonymous$$y reaction to that approach is that it would be considerable work (just exa$$anonymous$$e the interface for BaseInput). If there were a new type of input system for which I'd expect public interest (say a new 3D input sensor for phones), this would be a reasonable project, but then I'd expect Unity would, at some point, support an industry wide standard. If your work involves creating a product that would be used by other developers in the future, expanding the BaseInput class and using it via inputOverride would make sense.
If I were given a project with the description I have from your post, what appears to be an internal project (it sounds like an 'installation') that leads to basically one software project, I wouldn't work from the plan of expanded Unity's EventSystem (BaseInput$$anonymous$$odule). If I already had some example code which took the input from packet data, or as I have experience in TCP/IP I/O, it would strike me as much simpler to use a substitute interface at the top level (in the manner I suggest above), rather than dive into EventSystem. I expect it would take longer, because the documentation on how that's done is limited. From what I read it turns out to be a very similar task, but at that lower level that brings with it the weight of Unity's framework (one must account for all requirements put upon BaseInput). The overall result would be the same thing, differing primarily on where it is implement, within Unity's EventSystem or as a 'cap' on top of it. Either way, the task is about the same. I'd just expect that providing a working BaseInput with limited documentation to devolve into a winding road.
An additional thought occurred to me, though. I haven't taken a dive into the question, but as Input is a static class interface, maybe I could derive from Input to generate ExInput, which means all that is in Input would be automatically inherited and I could simply override a few functions, and be done.
Your answer
Follow this Question
Related Questions
Input returns 0 until released and pressed again if held down before start of scene 0 Answers
Joystick Input - "3rd Axis" etc, not sure what works/doesn't 1 Answer
Managing input for several players using pads in the same computer. 1 Answer
Joystick Axis 9&10 with more than 2 gamepads 0 Answers
How to provide inputs via Script? 0 Answers