Skip to content

DarknessFX/UEPlaystationGamepad

Repository files navigation

 .----------------.  .----------------.  .----------------. 
| .--------------. || .--------------. || .--------------. |
| |  ________    | || |  _________   | || |  ____  ____  | |
| | |_   ___ `.  | || | |_   ___  |  | || | |_  _||_  _| | |
| |   | |   `. \ | || |   | |_  \_|  | || |   \ \  / /   | |
| |   | |    | | | || |   |  _|      | || |    > `' <    | |
| |  _| |___.' / | || |  _| |_       | || |  _/ /'`\ \_  | |
| | |________.'  | || | |_____|      | || | |____||____| | |
| |              | || |              | || |              | |
| '--------------' || '--------------' || '--------------' |
 '----------------'  '----------------'  '----------------' 

       DarknessFX @ https://dfx.lv | Twitter: @DrkFX

Playstation Gamepad For Unreal Engine 5.2


Playstation Gamepad For Unreal Engine 5.2 using Raw Input and Enhanced Input. This project is setup to enable DualShock3/Sixaxis, DualShock4 and DualSense controllers to bind with Unreal Engine Gamepad object, you can use your Playstation controllers for Gameplay, CommonUI, EnhancedInput with the same Gamepad code like other XInput gamepads instead of fork to GenericUSBController.

About

Originally to make DualShock 4 work with Unreal Engine 4 was just a list of RawInputWindows Plugin settings and was simpler to describe like in this forum post [Tutorial] UE4 using Dualshock4 controller (via USB, PS4 DS4 Gamepad).

Now that Unreal Engine 5.2 is moving the input system to Enhanced Input there are more files and structures to setup and isn't that simple to explain in a forum post, so this project is the easier way to share this information and give a demostration template working that can be copied to other projects.

Notes

  • You can have all 3 controllers connected to your PC USB.
  • If you have a DualShock4 1st Generation (Product ID 0x05C4) the project will inform you with a screen message, I don't have one to test but if you have (and want to contribute) send the RawInput Settings to me.
  • Basic Enhanced Input Action setup (only Buttons and Axes - Pressed and Released), for more information how to expand and create more Input Actions check Enhanced Input - An overview of the Enhanced Input Plugin. and Enhanced Input in UE5 - Official Tutorial.

DPad compatibility with CommonUI

Playstation gamepads DPad use Axis1D directional inputs, the Axis1D register from 0.0f to 8.0f : 0=Top, 2=Right, 4=Bottom, 6=Left, 8=No Input.

Unreal Engine don't expect DPad directions from axis values, only as buttons pressed/released, to enable compatibility with CommonUI, EnhancedInput and other XInput gamepads you need to modify the RawInput Plugin with the following changes:

If you prefer you can download my source files from:
RawInputWindows.h
RawInputWindows.cpp

Engine\Plugins\Experimental\RawInput\Source\RawInput\Public\Windows\RawInputWindows.h
Line 329 at the end of the file, add :

//Playstation DPad
FName DPadMap[7] = {};
struct PlaystationID {
	int32 vID; // VendorID
	int32 pID; // ProductID
	int32 aID; // Array Index
} psID[3];

Engine\Plugins\Experimental\RawInput\Source\RawInput\Private\Windows\RawInputWindows.cpp
Line 84, inside void FRawWindowsDeviceEntry::InitializeNameArrays(), add :

	DPadMap[0] = FGamepadKeyNames::DPadUp;
	DPadMap[2] = FGamepadKeyNames::DPadRight;
	DPadMap[4] = FGamepadKeyNames::DPadDown;
	DPadMap[6] = FGamepadKeyNames::DPadLeft;

	psID[0] = { 1356, 1476, 4 }; // DS4 GEN1
	psID[1] = { 1356, 2508, 4 }; // DS4 GEN2
	psID[2] = { 1356, 3302, 7 }; // DualSense

Line 1049, inside if (DeviceEntry.bNeedsUpdate) { before the endif }, add :

			for (PlaystationID& ps : psID) {
				if (DeviceEntry.DeviceData.VendorID == ps.vID && DeviceEntry.DeviceData.ProductID == ps.pID) {
					FAnalogData* DPadAxis1D = &DeviceEntry.AnalogData[ps.aID];
					int iPrevValue = FMath::FloorToInt(DPadAxis1D->PreviousValue);
					int iValue = FMath::FloorToInt(DPadAxis1D->Value);
					bool bIsRepeat = iValue == iPrevValue;

					if (!bIsRepeat) {
						if (iPrevValue != 8) {
							if (iPrevValue % 2 == 1) {
								MessageHandler->OnControllerButtonReleased(DPadMap[iPrevValue - 1], UserId, DeviceId, bIsRepeat);
								iPrevValue++;
								if (iPrevValue == 8) iPrevValue = 0;
							}
							MessageHandler->OnControllerButtonReleased(DPadMap[iPrevValue], UserId, DeviceId, bIsRepeat);
						}

						if (iValue != 8) {
							if (iValue % 2 == 1) {
								MessageHandler->OnControllerButtonPressed(DPadMap[iValue - 1], UserId, DeviceId, bIsRepeat);
								iValue++;
								if (iValue == 8.0f) iValue = 0.0f;
							}
							MessageHandler->OnControllerButtonPressed(DPadMap[iValue], UserId, DeviceId, bIsRepeat);
						}
						DPadAxis1D->PreviousValue = DPadAxis1D->Value;
					}
				}
			}
		}
	}
}

Credits

Unreal Engine from Epic Games - https://www.unrealengine.com/
Playstation DualShock4 Icons by Arks - https://arks.itch.io/ps4-buttons
Equ1no0x - DualShock4 Gen1 contribution.

License

@Unlicensed - Free for everyone and any use.

DarknessFX @ https://dfx.lv | Twitter: @DrkFX
https://github.com/DarknessFX/UEPlaystationGamepad