Need some insight into the custom input workflow and best practices.
My current state of understanding of the input device plugin system
The best way to pass float data and / or toggle data is through OnControllerAnalog and OnControllerButtonPressed / Released.
The best way to pass rotation, position and other assorted data types from the device to the game would be to create scene components and use the hardware SDK to query the hardware state.
Is this is most efficient way to read the hardware data.
If not, then I can read the hardware state in the IInputDevice’s Tick function using the hardware SDK. How can reference the data in game.
I am assuming that IInputDevice works on a separate thread than the main so querying hardware state would be best inside its Tick function and passed to the component, rather than querying the hardware state inside a scene component.
Could you please shed some light of the broader workings / schemas / flowcharts.
If you’re binding a joystick like input where the inputs are either an axis or a float value, then yes using input mapping is the cleanest way to read that input. If on the other hand you provide more data, e.g. a 3d position and orientation like a motion controller or a tracked device, then feeding that into Motion Controller abstraction or a custom component will probably end up being cleaner. If you make a custom component it can then have multicast delegate events you can subscribe to in blueprint or in code which can pass all the relevant data in context. This is IMO the recommended route for complex input devices or if you want to provide flexibility.
Any of the input plugins in my signature can serve as an example of different input methods. E.g. the myo plugin chiefly exposes input mapping, the leap motion has a complex plugin and exposes whole blueprint widgets, the hydra plugin binds to the motion controller abstraction so it will work similarly to the touch or the vive motion controllers. There’s also the archived realsense plugin which had multi-threading handled in UE4, but I would now recommend using background lambdas found in Zip-Utility as they are cleaner. These are all open source MIT so go ahead and take a look at the repos to see real code examples.
Regarding threading, everything runs in game thread unless otherwise specified, so if your device doesn’t handle threading by itself you will have to handle threading yourself e.g. make an FRunnable or a background thread Lambda.
Also note that if you want to receive a tick without needing to attach to an actor or placing anything in world, extend from an InputDeviceModule with an input device which will send two function calls:
virtual void SendControllerEvents() override
and
virtual void Tick(float DeltaTime) override
both of these run on the game thread for an example see the FHydraPlugin private class, which uses this setup.
As everything runs on the game thread, there would be no performance difference if the third party sdk is called from either a scene component or inputdevice or blueprint function library.
Also if FRunnable can be used from either one of them then I guess the only reason to derive from Input device is to provide custom input axis keys for events , which again can be provided as events on the scene component.
If FRunnable cannot be only be used inside IInputDevice then it would be better to use InputDevice for those input events.
P.S. Something like Leap::Controller.frame() inside a TickComponent would be same as Leap::Controller.frame() inside a SendControllerEvents() in the InputDevice performance wise.
I tried to copy the X360CE_X64.EXE file to “Program Files\WindowsApps\Microsoft.ApexPC” folder but I get “Folder Access Denied” and “You’ll need to provide administrator permission to copy to this folder” messages. How can I fix this problem? I have Windows 10.