First off, the plugin works. The Input devices are available in blueprints, they compile and the functionality is there. The issue is that all of my inputs have the warning “InputKey Event specifies invalid FKey.”
This is the InputDevice class:
#include "HRF_Controller.h"
#include "HRF.h"
#include "HAL/PlatformTime.h"
#include "HAL/PlatformProcess.h"
#include "Misc/Paths.h"
#include "GenericPlatform/GenericApplicationMessageHandler.h"
#include "Modules/ModuleManager.h"
#include "GenericPlatform/IInputInterface.h"
#include "IInputDevice.h"
#include "IInputDeviceModule.h"
#include "GameFramework/InputSettings.h"
#define LOCTEXT_NAMESPACE "HRFController"
namespace HRFControllerKeyNames {
// HHL Button Key Names
const FGamepadKeyNames::Type HRF_Button1("HRF_Button1");
const FGamepadKeyNames::Type HRF_Button2("HRF_Button2");
const FGamepadKeyNames::Type HRF_Button3("HRF_Button3");
const FGamepadKeyNames::Type HRF_Button4("HRF_Button4");
const FGamepadKeyNames::Type HRF_Button5("HRF_Button5");
}
namespace HRFControllerKeys {
// HRF Button Keys
const FKey HRF_Button1("HRF_Button1");
const FKey HRF_Button2("HRF_Button2");
const FKey HRF_Button3("HRF_Button3");
const FKey HRF_Button4("HRF_Button4");
const FKey HRF_Button5("HRF_Button5");
}
class FHRFController : public IInputDevice {
public:
FHRFController(const TSharedRef< FGenericApplicationMessageHandler >& InMessageHandler) :
MessageHandler(InMessageHandler) {
// HRF Buttons
EKeys::AddKey(FKeyDetails(HRFControllerKeys::HRF_Button1, LOCTEXT("HRF_Button1", "HRF_Button1"), FKeyDetails::GamepadKey));
EKeys::AddKey(FKeyDetails(HRFControllerKeys::HRF_Button2, LOCTEXT("HRF_Button2", "HRF_Button2"), FKeyDetails::GamepadKey));
EKeys::AddKey(FKeyDetails(HRFControllerKeys::HRF_Button3, LOCTEXT("HRF_Button3", "HRF_Button3"), FKeyDetails::GamepadKey));
EKeys::AddKey(FKeyDetails(HRFControllerKeys::HRF_Button4, LOCTEXT("HRF_Button4", "HRF_Button4"), FKeyDetails::GamepadKey));
EKeys::AddKey(FKeyDetails(HRFControllerKeys::HRF_Button5, LOCTEXT("HRF_Button5", "HRF_Button5"), FKeyDetails::GamepadKey));
// Wait for HRF_ToolServer.exe to load
FPlatformProcess::Sleep(2);
hrf = MakeShareable<HRF>(new HRF());
}
virtual ~FHRFController() {
}
virtual void Tick(float DeltaTime) override {
}
virtual void SendControllerEvents() override {
// Get States
hrf->GetState(HRF_A);
// Check Button1
if (HRF_A.Button1 != HRF_B.Button1) {
if (HRF_A.Button1 == 1) {
MessageHandler->OnControllerButtonPressed(HRFControllerKeys::HRF_Button1.GetFName(), 0, false);
}
else {
MessageHandler->OnControllerButtonReleased(HRFControllerKeys::HRF_Button1.GetFName(), 0, false);
}
}
// Check Button2
if (HRF_A.Button2 != HRF_B.Button2) {
if (HRF_A.Button2 == 1) {
MessageHandler->OnControllerButtonPressed(HRFControllerKeys::HRF_Button2.GetFName(), 0, false);
}
else {
MessageHandler->OnControllerButtonReleased(HRFControllerKeys::HRF_Button2.GetFName(), 0, false);
}
}
// Check Button3
if (HRF_A.Button3 != HRF_B.Button3) {
if (HRF_A.Button3 == 1) {
MessageHandler->OnControllerButtonPressed(HRFControllerKeys::HRF_Button3.GetFName(), 0, false);
}
else {
MessageHandler->OnControllerButtonReleased(HRFControllerKeys::HRF_Button3.GetFName(), 0, false);
}
}
// Check Button4
if (HRF_A.Button4 != HRF_B.Button4) {
if (HRF_A.Button4 == 1) {
MessageHandler->OnControllerButtonPressed(HRFControllerKeys::HRF_Button4.GetFName(), 0, false);
}
else {
MessageHandler->OnControllerButtonReleased(HRFControllerKeys::HRF_Button4.GetFName(), 0, false);
}
}
// Check Button5
if (HRF_A.Button5 != HRF_B.Button5) {
if (HRF_A.Button5 == 1) {
MessageHandler->OnControllerButtonPressed(HRFControllerKeys::HRF_Button5.GetFName(), 0, false);
}
else {
MessageHandler->OnControllerButtonReleased(HRFControllerKeys::HRF_Button5.GetFName(), 0, false);
}
}
// Set HRF_B = HRF_A -> Repeat
HRF_B = HRF_A;
// End HRF stuff
}
void SetChannelValue(int32 ControllerId, FForceFeedbackChannelType ChannelType, float Value) override {
}
void SetChannelValues(int32 ControllerId, const FForceFeedbackValues &Values) override {
}
void UpdateVibration(int32 ControllerId, const FForceFeedbackValues& ForceFeedbackValues) {
}
virtual void SetMessageHandler(const TSharedRef< FGenericApplicationMessageHandler >& InMessageHandler) override {
MessageHandler = InMessageHandler;
}
virtual bool Exec(UWorld* InWorld, const TCHAR* Cmd, FOutputDevice& Ar) override {
return false;
}
virtual bool IsGamepadAttached() const override {
return true;
}
private:
TSharedRef<FGenericApplicationMessageHandler> MessageHandler;
TSharedPtr<HRF> hrf;
HRF_State HRF_A, HRF_B;
};
class FHRFControllerPlugin : public IInputDeviceModule {
virtual TSharedPtr< class IInputDevice > CreateInputDevice(const TSharedRef< FGenericApplicationMessageHandler >& InMessageHandler) override {
return TSharedPtr< class IInputDevice >(new FHRFController(InMessageHandler));
}
};
#undef LOCTEXT_NAMESPACE // HRFController
IMPLEMENT_MODULE(FHRFControllerPlugin, HRFController)
When I load the editor, I get the following warning:
Inside my Blueprint before hitting compile:
After Compile:
Output Log while running, using the input device:
So everything is working. I have tried placing the plugin folder in my project’s plugins folder as well as both the Runtime and Developer folders in the Engine Plugins (not at the same time). I keep getting the warning messages. What am I missing? It works, but I can’t release this with those messages. I am unable to show the HRF class due to IP issues but it mainly contains details about communicating with the device and updating its state → the HRF_State struct. The HRF_ToolServer.exe which is mentioned in the code is a UDP server that allows programs to communicate with devices that we use as controllers → the HRF controller is one of those devices.