Just want to second @Soar in thanking @schuan for this plugin. Was in a similar situation trying to get keyboard + controller to work in 5.3.2 and it resolved the issue immediately. Definitely recommend for anyone trying this in 5.3.
Hi, dont work for me, I use the version 5.3.2, but it not compile… can you help me?
UE 5.5 here and issue is still present.
Unfortunately the PlatformUserId is not the only issue here. In my setup of keyboard and 2 XBOX Series Gamepads (Wireless + Wired) only recognizes 2 DeviceIds and thus creates 2 PlatformIds on start. Sometimes it recogniezes 3 DeviceIds and third one is a None which is although Connected. Changing focus on window also changes the Gamepads assignments. I spent 3 days on this and I can only call it a disaster.
I finally found a way to force proper controller assignments in UE 5.5. This is purely Xinput solution so only for Xbox Controllers. You need to take Xinput Plugin from engine and place it in project under Plugins/Runtime/Windows/XinputDevice (or edit in engine if from GitHub).
Next edit the GetPlatformUserAndDevice method as below.
You also need to add “EngineSettings” module to plugin’s build.cs.
This is a temporary fix that will most likely fail to work on consoles and other gamepads. I didn’t test dynamic reassignemnts as well.
/*
* Fix/Hack for Gamepad mapping so it omits assigning the first controller to first player when requested
*/
void XInputInterface::GetPlatformUserAndDevice(int32 InControllerId, EInputDeviceConnectionState InDeviceState, FPlatformUserId& OutPlatformUserId, FInputDeviceId& OutDeviceId)
{
bool bSkipPlayer1 = UGameMapsSettings::GetGameMapsSettings()->GetSkipAssigningGamepadToPlayer1();
if (bIsPrimaryDevice)
{
if (bSkipPlayer1)
{
InControllerId = InControllerId + 1;
}
IPlatformInputDeviceMapper& DeviceMapper = IPlatformInputDeviceMapper::Get();
DeviceMapper.RemapControllerIdToPlatformUserAndDevice(InControllerId, OUT OutPlatformUserId, OUT OutDeviceId);
//Check if this controller was already assigned because it can be in Unknown state for some reason... And we don't want to pass it every time as we're going to be spammed with UI Editor messages
TArray<FInputDeviceId> Devices;
DeviceMapper.GetAllInputDevicesForUser(OutPlatformUserId, Devices);
bool bDeviceIsAdded = Devices.Contains(OutDeviceId);
if (InDeviceState == EInputDeviceConnectionState::Connected || InDeviceState == EInputDeviceConnectionState::Disconnected || !bDeviceIsAdded)
{
DeviceMapper.Internal_MapInputDeviceToUser(OutDeviceId, OutPlatformUserId, InDeviceState);
}
}
else
{
OutDeviceId = FInputDeviceId::CreateFromInternalId(InControllerId);
}
}
It may be that the examples used in the class of this plugin will also help. And there are also examples of how to implement local multiplayer in the game mode.