How do I handle input from a custom input device?

Hi guys

I’d like to write a plugin to add support for custom (and unconventional) input devices (for instance, some strange device we make with Arduino e co.). I know how to write an Unreal plugin but I’d like to know what is the best way to build a plugin to use an external input device.

In particular, I thought at two main directions:

  1. I have to extend IInputDeviceModule and create a new IInputDevice? Unfortunately this part is really undocumented.
  2. Otherwise, it is a valid option to write some custom Blueprint functions that return the input device state? Or a custom Blueprint event that return the device state at each frame? Do you think it is too much performance consuming?

Any tips that can bring me on the right direction is really appreciated.

Hi,

lion032 figured it out for his Kinect Plugin (The following are excerpts from his github code, all credit to him)

you can see where the IInputDevice you make will come to life in *Application.cpp files

I.E. In WindowsApplication.cpp → PollGameDeviceState( … )

	if (!bHasLoadedInputPlugins)
	{
		TArray<IInputDeviceModule*> PluginImplementations = IModularFeatures::Get().GetModularFeatureImplementations<IInputDeviceModule>( IInputDeviceModule::GetModularFeatureName() );
		for( auto InputPluginIt = PluginImplementations.CreateIterator(); InputPluginIt; ++InputPluginIt )
		{
			TSharedPtr<IInputDevice> Device = (*InputPluginIt)->CreateInputDevice(MessageHandler);
			if ( Device.IsValid() )
			{
				ExternalInputDevices.Add(Device);
			}
		}

		bHasLoadedInputPlugins = true;
	}

This bit will run immediately after game play first starts, and will run through once

	// Poll externally-implemented devices
	for( auto DeviceIt = ExternalInputDevices.CreateIterator(); DeviceIt; ++DeviceIt )
	{
		(*DeviceIt)->Tick( TimeDelta );
		(*DeviceIt)->SendControllerEvents();
	}
}

And this bit will run every poll, checking all the custom input devices (I.E. your ones)



Your plugin modules .h file will need to extend IInputDeviceModule like the skeleton below. If it does it will appear in the array of IInputDeviceModules that the *Application initializes on the first game state poll (shown above)

IYourPluginName.h

#pragma once
 
#include "ModuleManager.h"
#include "IInputDeviceModule.h"
 
class I*YourPluginName* : public IInputDeviceModule {
public:
    static inline I*YourPluginName*& Get()
	{
		return FModuleManager::LoadModuleChecked< I*YourPluginName* >("YourPluginHandel");
	}

	static inline bool IsAvailable()
	{
		return FModuleManager::Get().IsModuleLoaded( "YourPluginHandel" );
	}
}

Your plugin modules .cpp file will need to implement IInputDeviceModule’s CreateInputDevice method in addition to the usual suspects.

YourPluginName.cpp

class F*YourPluginName* : public I*YourPluginName*
{
	virtual TSharedPtr< class IInputDevice > CreateInputDevice(const TSharedRef< FGenericApplicationMessageHandler >& InMessageHandler);

    // *+ other stuff...*
};

IMPLEMENT_MODULE(F*YourPluginName*, *YourPluginHandel*)

TSharedPtr< class IInputDevice > FKinectV2Plugin::CreateInputDevice(const TSharedRef< FGenericApplicationMessageHandler >& InMessageHandler)
{
	return MakeShareable(new F*YourInputDeviceName*(InMessageHandler));
}

// *+ other stuff...*


Create your device class similar to XInputDevice in the codebase, check lions KinectV2InputDevice for a refrence if your not sure what to do…

Best of luck :slight_smile:

Thanks for your answer, I’m new to windows programming and I still have a question about custom input device hook up.

After looking into LogiWheel SDK and code samples, I found out that the code process messages appear in the main window. )

How can I handle those messages in an Unreal way? or just modify ‘WindowsApplication’ and store everything in AppWndProc?

I have written a plugin (that I can’t share/distribute due to the underlying library licences) to provide UE4 with Nintendo Wii motion controller/classic controller/board/guitar/e.t.c. support. It communicates with whatever MessageHandler UE4 is using (the default platforms MessageHandler or any overrides due to other plugins/source edits) so will work in windows/mac/linux/foo/bar/e.t.c.

In the next few days I’ll rip the guts out of the code to make it a tutorial project replacing the wii controller libraries with psudo input controller libraries as an example of how to add controllers in an Unreal friendly way.

Just got back from holiday though so ill need a few days to get on my feet again :slight_smile:

(Watch this space and harass me if I forget)

EDIT:

I’m planning on beginning an open source VRPN intergration plugin with Joachim (which will give support for a large list of controller devices, potentially all VRPN supported devices). I don’t know if VRPN currently supports the logiwheel or not, but if it does this could be a nice unbrella to do it under rather than making a standalone plugin.

Extending IInputDeviceModule is the best option if you are using a controller that is ‘traditional’, such as a 6-axis controller and/or a d-pad and/or dimond pattern buttons like the xbox or a playstation.

This sets you up to communicate with the GenericApplicationMessageHandler which comes preloaded with nice EButtons like axis’ LeftJoystickUp/LeftJoystickRight and buttons like Start/RightShoulder

This will let you accesss the input device in a generic way, so developers using your plugin don’t need to care whether its a playstation controller, or a modified NES controller thats been plugged in.

If you have an input device a lot more outside the square and some of its features don’t realy fit any of the generic EButton labels (like the 4 weight sensors on a Wii Balance Board, or some science fiction spinal cord implant) then you should add your own custom EKey objects to represent your much stranger needs.

(IMO The balance board would idealy use the MessageHandler for the A key on the front, and map each of the sensors to new EKey axis’)

I’ll post a tutorial on both of these approches soonish and add a link to it here.

For some reason using VRPN is not an option for my project. Looking forward to your Tutorial. Great thanks~

I have added a wiki page about creating input devices. I’m on holiday for the next 9 days so can’t tidy it up, but in the mean time it should be enough to get anyone started :slight_smile:

Here is a tutorial :slight_smile:

It shows you how to make a custom input device. Just load it up with your favourite 3rd party libary to make a custom wii controller input, or anything else that strikes your fancy.

It shows how to hook up your custom input to the existing button/analog/gesture types unreal knows about. And how to create new ones (The example uses a psudo a weight sensor that always outputs 75 units).

Have fun, if you have any questions/problems just comment on the tutorial (I’ll be watching)

:slight_smile: