CommonUI: Switch CommonInputBaseControllerData at Runtime?

Hi there…

I’m nearly done finishing my UI and now got stuck in a Problem… which i thought CommonUI takes care of…

I want my Players to be able to change the Theme of the Gamepad Icons…

Technically, CommonUI has the CommonInputBaseControllerData Assets… which you can add to an Array to the CommonInputSettings.

Right now, my Array looks like this:
0: XBox_Dark
1: KeyboardMouse
2: XBox_Light
3: PS_Dark
4: PS_Light

The InputActionWidgets, the ActionBar and all that stuff is working well.
But… it always uses the XBox theme for the Gamepad, simply cause the GamepadInputType for all Themes is “Generic” only… no additional Names available… And it takes the first theme corresponding of the Input Device, from the Array.

So… how can i set any other of the Gamepad Themes to be the current used one?
(BP and/or C++)

To be clear: I’m not using any Platform SDK (Playstation, Switch, XBox)… i just want to have Gamepad-Icon-Themes.

So there has to be a way to add new Gamepad Names… or else this whole Array is pretty useless

bumping this up - Still couldn’t find a solution…

bump again…

Ok Guys… For over 2 Weeks i got no response…

But a really nice Guy from the Unreal Source Discord (@sp1r1t_d1tch, you are my Hero!!!) gave me the Solution.

1st:
I created a new class inherited from UCommonInputBaseControllerData:

// Header
#pragma once

#include "CoreMinimal.h"
#include "CommonInputBaseTypes.h"
#include "YourNewControllerDataClassName.generated.h"

UCLASS()
class YOURGAME_API UYourNewControllerDataClassName : public UCommonInputBaseControllerData
{
	GENERATED_BODY()

public:
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="Gamepad")
	FName GamepadNameOverride = FName("");
	
	UYourNewControllerDataClassName();

	void UpdateGamepadName();
};
// Source
#include "YourNewControllerDataClassName.h"

UYourNewControllerDataClassName ::UYourNewControllerDataClassName ()
{
	GamepadName = GamepadNameOverride;
}

void UYourNewControllerDataClassName ::UpdateGamepadName()
{
	GamepadName = GamepadNameOverride;
}

This overrides the GamepadName on Construct. But… we wanna have a method to update it when already existing… just by giving our ControllerData a new Parent class…

Therefor… i added a Button…

We need this Customization Class:

// Header

#pragma once

#include "CoreMinimal.h"
#include "IDetailCustomization.h"
#include "DetailLayoutBuilder.h"
#include "YourNewControllerDataClassName.h"

class FYourCustomization : public IDetailCustomization
{
public:
	static TSharedRef<IDetailCustomization> MakeInstance();

	virtual void CustomizeDetails(IDetailLayoutBuilder& DetailLayout) override;

private:
	FReply OnUpdateGamepadNameClicked();

	// Store a pointer to the object being customized
	UYourNewControllerDataClassName* CustomizedObject;
};
// Source

#include "FYourCustomization.h"
#include "DetailCategoryBuilder.h"
#include "DetailWidgetRow.h"
#include "IDetailChildrenBuilder.h"
#include "Widgets/Input/SButton.h"
#include "Widgets/Text/STextBlock.h"
#include "Editor/PropertyEditor/Public/PropertyEditorModule.h"
#include "Modules/ModuleManager.h"

#define LOCTEXT_NAMESPACE "FYourCustomization"

TSharedRef<IDetailCustomization> FYourCustomization::MakeInstance()
{
	return MakeShareable(new FYourCustomization);
}

void FYourCustomization::CustomizeDetails(IDetailLayoutBuilder& DetailLayout)
{
	// Get the object being customized
	TArray<TWeakObjectPtr<UObject>> ObjectsBeingCustomized;
	DetailLayout.GetObjectsBeingCustomized(ObjectsBeingCustomized);

	if (ObjectsBeingCustomized.Num() > 0)
	{
		CustomizedObject = Cast<UYourNewControllerDataClassName>(ObjectsBeingCustomized[0].Get());
	}

	IDetailCategoryBuilder& CustomCategory = DetailLayout.EditCategory("Gamepad");

	CustomCategory.AddCustomRow(LOCTEXT("UpdateGamepadName", "Update Gamepad Name"))
	.ValueContent()
	[
		SNew(SButton)
		.Text(LOCTEXT("UpdateGamepadNameButton", "Update Gamepad Name"))
		.OnClicked(FOnClicked::CreateSP(this, &FYourCustomization::OnUpdateGamepadNameClicked))
	];
}

FReply FYourCustomization::OnUpdateGamepadNameClicked()
{
	if (CustomizedObject)
	{
		UE_LOG(LogTemp, Warning, TEXT("Calling UpdateGamepadName on %s"), *CustomizedObject->GetName());
		CustomizedObject->UpdateGamepadName();
	}
	else
	{
		UE_LOG(LogTemp, Warning, TEXT("CustomizedObject is null"));
	}

	return FReply::Handled();
}

#undef LOCTEXT_NAMESPACE

And we need to implement this to our Modules

You Modules normally are the Projectname.h and Projectname.cpp Files, in your Source Root Directory.

// Module Header
#pragma once

#include "CoreMinimal.h"

class F<ProjectName>Module : public FDefaultGameModuleImpl
{
public:
	virtual void StartupModule() override;
	virtual void ShutdownModule() override;
};
// Module Source
// <Projectname>.cpp

#include "<Projectname>.h"
#include "Modules/ModuleManager.h"
#include "PropertyEditorModule.h"
#include "YourCustomization.h"

IMPLEMENT_PRIMARY_GAME_MODULE(F<Projectname>Module, <Projectname>, "<Projectname>");

void F<Projectname>Module::StartupModule()
{
	// Register customizations
	FPropertyEditorModule& PropertyModule = FModuleManager::LoadModuleChecked<FPropertyEditorModule>("PropertyEditor");
	PropertyModule.RegisterCustomClassLayout("YourNewControllerDataClassName", FOnGetDetailCustomizationInstance::CreateStatic(&FYourCustomization::MakeInstance));
	PropertyModule.NotifyCustomizationModuleChanged();
}

void F<Projectname>Module::ShutdownModule()
{
	// Unregister customizations
	if (FModuleManager::Get().IsModuleLoaded("PropertyEditor"))
	{
		FPropertyEditorModule& PropertyModule = FModuleManager::GetModuleChecked<FPropertyEditorModule>("PropertyEditor");
		PropertyModule.UnregisterCustomClassLayout("YourNewControllerDataClassName");
	}
}

Resulting in:
image

Which now allows to Type in ANY new name in the Gamepad name Override… hit the Button… done…
image
Works…

Ps.:
If you have existing CommonInputBaseControllerData Assets, open them and head to the “Class Default”. At the top, select the Box for Parent Class and select your own Class there… the Button and Override Input immediately will appear, ready for all mischiefs :wink:

1 Like

Thanks, bro, it’s really helpful.