Why does left mouse click register when i press gamepad face button bottom on gamepad?

Hello! I’ve had this issue for quite some time but I can’t find a way to change this. I believe this is set by default from what I’ve read but can it be changed?

Basically whenever I press gamepad face button bottom (or A in xbox controllers) it is registered as a left click, which messes around with my gamepad customizable keybinds and actions that I want to bind to that key in widgets.

1 Like

Fairly certain that’s controlled by SetInputMode() on the PlayerController. So if you use FInputModeGameOnly, it’ll do what you want, but I think the mouse won’t work on the interface either.

If you need the mouse to still work, then disregard what I just mentioned. You can instead disable the default UI actions on the gamepad. I believe those are stored in the project settings under Common Input Settings, Input Data. You should have a data table somewhere that uses that table definition. If the class name is GenericInputData, then you need to duplicate GenericInputData and the GenericInputActionDataTable. Go into the duplicate of GenericInputData and change the table to the new one for both entries. Then update your table to not cause the accept action. It’s in the GenericAccept row and set the gamepad key to None. You could also try setting Override State to Disabled. I haven’t messed around much with this.

If you want to get rid of all the defaults, just remove the table reference from the two entries in the dupe GenericInputData reference.

Don’t forget to set the GenericInputData duplicate in your project settings.

1 Like

EDIT: As @Benmolenaar1 correctly pointed out, this only works in UE 5.4+ so bear that in mind. He has posted his solution which should work pre 5.4.

I have had the same problem using CommonUI. UCommonUIActionRouterBase creates a FCommonAnalogCursor to simulate mouse clicks when using a Gamepad. This is how it makes the entire UI navigation work with Gamepad. FCommonAnalogCursor has a virtual function

virtual bool ShouldVirtualAcceptSimulateMouseButton(const FKeyEvent& InKeyEvent, EInputEvent InputEvent);

that controls whether Accept inputs (Face Button Bottom) should be emulated as mouse clicks. For me, it was enough to override this and only return true when the Current InputMode was not GameOnly.

Here is my code:
.h

#pragma once
#include <CoreMinimal.h>
#include <Input/CommonUIActionRouterBase.h>
#include <Input/CommonAnalogCursor.h>

#include "CcCommonUIActionRouter.generated.h"

class FCcCommonAnalogCursor : public FCommonAnalogCursor
{
public:
	FCcCommonAnalogCursor(const UCommonUIActionRouterBase& InActionRouter) : FCommonAnalogCursor(InActionRouter) {}

public:
	bool ShouldVirtualAcceptSimulateMouseButton(const FKeyEvent& InKeyEvent, EInputEvent InputEvent) const override;

};

UCLASS()
class UCcCommonUIActionRouter : public UCommonUIActionRouterBase
{
	GENERATED_BODY()

protected:
	TSharedRef<FCommonAnalogCursor> MakeAnalogCursor() const override;

};

.cpp

#include "CcCommonUIActionRouter.h"

#include <Engine/EngineBaseTypes.h>
#include <Input/Events.h>


bool FCcCommonAnalogCursor::ShouldVirtualAcceptSimulateMouseButton(const FKeyEvent& InKeyEvent, EInputEvent InputEvent) const
{
	return ActionRouter.GetActiveInputMode() != ECommonInputMode::Game;
}

TSharedRef<FCommonAnalogCursor> UCcCommonUIActionRouter::MakeAnalogCursor() const
{
	return FCommonAnalogCursor::CreateAnalogCursor<FCcCommonAnalogCursor>(*this);
}

Note that you need to include Slate as a dependency in your Build.cs.

2 Likes

Could you please help me do it step by step? I’ve never used C++

1 Like

I thought i’d solved it but it turns out that my last solution was incorrected. A workaround that is working for me though is to not use the same input setting for trigger/left click, so instead of having 1 action mapping for shoot that used both buttons, i created an action mapping for ShootController, and one for ShootMouse, seems to working okay.

Thanks @voodoo_jannick! Your solution worked pretty well for me.

1 Like

Oh lord what a nice person! Thanks for sharing.

For anyone else with this doubt: Where do I replace UCommonUIActionRouterBase so CommonUI uses my UCcCommonUIActionRouter subsystem?

UCommonUIActionRouterBase::::ShouldCreateSubsystem holds the answer!

bool UCommonUIActionRouterBase::ShouldCreateSubsystem(UObject* Outer) const
{
	TArray<UClass*> ChildClasses;
	GetDerivedClasses(GetClass(), ChildClasses, false);

	UE_LOG(LogUIActionRouter, Display, TEXT("Found %i derived classes when attemping to create action router (%s)"), ChildClasses.Num(), *GetClass()->GetName());

	// Only create an instance if there is no override implementation defined elsewhere
	return ChildClasses.Num() == 0;
}

So basically, if there is a child class like ours, it won’t create the default UCommonUIActionRouterBase, and ours will exist!

1 Like

Hey, I would really appreciate if you made a step by step guide on how to implement this code in the project since I’m really new c++ and unreal so I’m pretty clueless.

If you need a step by step guide on how to create C++ classes and extend other classes I would recommend learning more about that first. There are plenty of good tutorials out there and once you understand the basics, you can easily do what I did with the provided code sample!

1 Like

The c++ solution provided by voodoo_jannick is only applicable in version 5.4+, as the ShouldVirtualAcceptSimulateMouseButton boolean does not exist prior to 5.4.

I found a workaround using Blueprint. On the OnKeySelected function of the InputKeySelector, you can pass the Selected Key to a function which checks what the input type is and return a key based on this. If input type is Mouse/Keyboard then return Left Mouse Button, or if it’s Gamepad then return Face Button Bottom.

I can’t add more screenshots because Epic thinks my account is new, but essentially you can just plug the output of the OnKeySelected event to this function. Then you can update the InputKeySelector Mapping using this key

This works for my use case. Hope it helps someone out there.

1 Like

I’ve managed to get it working, thanks a lot I really appreciate it.