Is there a way to detect a gamepad?

Is there a way to detect if a controller is connected or is there an event called when a gamepadis connected?
Also is there a generic event for getting input from a gamepad(if any button is hit for example)?

It would be used for switching menu navigation icons for example. Press “B” to go back instead of “esc” whether or not a gamepad is connected.

Under Project Settings/Input you’ll find where to create key bindings. You can assign “Esc” and “Gamepad_FaceButton_Bottom” to the same thing. In order to change HUD icons, Id just create a boolean somewhere in your HUD to either show PC icons or console icons, and set up a menu where your user can switch it to true or false. Not sure how you could do it by controller detection on a PC.

I guess I wasn’t clear enough. I am looking for a way to detect if a gamepad is connected to the computer physically.

Hi,

Unfortunately, there is no such function. But code you need lay in XInputInterface.cpp

/** Controller states */
FControllerState ControllerStates[MAX_NUM_XINPUT_CONTROLLERS];

This variable is private and XInputInterface has no function to get it. I think the simple way to access to that variable it is add interface that check gamepad.

GenericApplication.h

virtual bool IsGamepadConnected() { return false; }

WindowsApplication.h

virtual bool IsGamepadConnected() override;

WindowsApplication.cpp

bool FWindowsApplication::IsGamepadConnected()
{
	return XInput->IsGamepadConnected();
}

XInputInterface.h

bool IsGamepadConnected();

XInputInterface.cpp

bool XInputInterface::IsGamepadConnected()
{
	for (int32 ControllerIndex = 0; ControllerIndex < MAX_NUM_XINPUT_CONTROLLERS; ++ControllerIndex)
	{
		FControllerState& ControllerState = ControllerStates[ControllerIndex];
		if (ControllerState.bIsConnected)
			return true;
	}

	return false;
}

And call that where you need

TSharedPtr<GenericApplication> GenericApplication =  SlateApplication::Get().GetPlatformApplication();
GenericApplication->IsGamepadConnected();

In addition, I think it is not very good idea to do that, because we add very specific functions to general functionality. But I hope it will be a start point for solving your problem.

Cheers

2 Likes

Thanks for this! Since you said that this solution isn’t ideal, would it make it easier to toggle if any input is detected? For example a controller could be plugged in but until they hit a button/move a stick it’ll still be in “Keyboard” mode. Vice versa for switching from controller mode. Is there a function or utility to detect any keyboard/mouse input and any controller input?

I thought of a kludgy solution of creating an action mapping in project settings that just contains every key and every button/axis for keyboard/mouse and controller respectively. Definitely not the best idea but I think it’ll work.

Did you find solution to this particular problem? I’m also looking this solution.
However this problem is not crucial for me, since any games I played on PC, still enable keyboard inputs when gamepad controller is plugged.
Even though the binding (by name with associated default input button/key) is handled on Project Settings/Input, it will be nice if I can check whether a gamepad controller is plugged, so I can show/hide Gamepad Controller setting Menu on my Options Menu game (to set custom key binding from players).

I did not find a solution. However I mentioned a kludgy solution below creating an action mapping called “InputFromController” containing every controller button/axis in its inputs. Basically this will fire whenever a button or trigger is pressed. Not the most ideal solution, especially when I comes to the keyboard equivalent.

Yes, same with me. It’ll be helpful if there is key events for the UI like in the UObject, so we can bind smoothly.

This solution worked for me since I could rebuild my engine, but for coders who can’t rebuild their engines you can try the solution below that works based on some dark magic with #defines:

FWindowsApplication now has IsGamepadAttached() function

Here is possible solution, only tested on windows so far.

File - New C++ Class

Choose parent class - Blueprint Function Library, hit next

Give it a name ( GamepadDetection )

GamepadDetection.h

    #pragma once
    
    #include "CoreMinimal.h"
    #include "Kismet/BlueprintFunctionLibrary.h"
    #include "GamepadDetection.generated.h"
    
    /**
     * 
     */
    UCLASS()
    class YOURPROJECTNAME_API UGamepadDetection : public UBlueprintFunctionLibrary
    {
    	GENERATED_BODY()
    	
    public:
    	/* Check if gamepad is connected at Runtime. */
    	UFUNCTION(BlueprintCallable, meta = (DisplayName = "GamepadConnected"), Category = "System Information")
    		static bool IsGamePadConnected();
    	
    	
    };

GamepadDetection.cpp

    #include "GamepadDetection.h"
    #include "SlateBasics.h"
    
    bool UGamepadDetection::IsGamePadConnected()
    {
    	auto genericApplication = FSlateApplication::Get().GetPlatformApplication();
    	if (genericApplication.Get() != nullptr && genericApplication->IsGamepadAttached())
    	{
    		return true;
    	}
    	return false;
    }

Then finally uncomment / enable slate module dependencies within your projectname.Build.cs and reboot your editor before hitting compile.

YourProjectName.Build.cs

    // Uncomment if you are using Slate UI
    PrivateDependencyModuleNames.AddRange(new string[] { "Slate", "SlateCore" });

Now you have a node inside blueprint to check if the gamepad is connected,

1 Like

Well, I haven’t tried RhinoCode’s solution but based on the number of upvotes, it must work.
But in case you want a pure blueprint solution, this worked for me pretty well

The switch input is just a custom event in the HUD I made which executes custom logic to switch the HUD controls based on if the key pressed is on a controller or a keyboard

352518-screenshot-2021-11-18-151740.png

Just make sure your consume input bool in the details panel of the ‘any key’ is false so that all other inputs work fine

1 Like

Since this still shows up as one of the top threads on this topic:

Newer versions of Unreal have the CommonInput Subsystem which takes care of input events and device changes. You can simply bind an event to the input change like this:


and the delegate will give you the device. You can also get the current input type and many other things.

As a subsystem this is accessible from anywhere without having to add any components and it should work in UI as well as any other code classes.

EDIT: it should be noted that this is part of the CommonUI Plugin so it does require a tiny bit of setup as seen on the CommonUI docs, though it’s likely it’ll become one of the standard plugins for UE5 when it has matured a little bit.

4 Likes

Hello, I also encountered this problem.
I’ll tell you how I was able to solve it.