Hi Guys ,
This week I worked on dynamically binding input keyboard and mouse values based on user's choice in keyboard customization section. Here is how I did it.
First I created an excel table containing the following columns. I only gave two examples of keyboard actions, you will have as many rows as the number of different action event and key binding you want to have in your game.
Next I created a struct for my datatable in my HUD header class in C++. Make sure to add the following namespace
"Runtime/Engine/Classes/Engine/DataTable.h" in the header class.
Now define your datatable in HUD header -
and initialize it the HUD constructor class
I imported this excel as datatable in UE4 , inherited from the struct FKeyBoardBindingTable.
Then , I created userinterface class for keyboard configuration menu. , deriving from SCompounWidget , and wrote the UI in slate architecture. The UI is simple key customization UI that you can see in any game , when user clicks on an input , it asks you to bind it to a new value , then you have to press a key to bind to it. See below.
OK , and the below is my header class , in case you are confused with the above code.
Now you can easily add this UI in your viewport in your HUD class , whenever required , using the below line
Now our keyconfiguraiton UI is ready(please let me know if you find any bug). SO next I need to tell unreal engine , that whatever current value is present in the Input column of the datatable , I am supposed to use that for desired set of action. So for that I wrote the following code in my playercharacter class. Here , make sure you include the below namespaces
And thats it, when you hit on play , all this settings will be saved and you can verify by going to the project settings->input section.
Thanks and Regards ,
Sameek Kundu
This week I worked on dynamically binding input keyboard and mouse values based on user's choice in keyboard customization section. Here is how I did it.
First I created an excel table containing the following columns. I only gave two examples of keyboard actions, you will have as many rows as the number of different action event and key binding you want to have in your game.
Action | DefaultInput | Input | Category |
Primary Attack | MouseLeftButton | MouseLeftButton | Combat |
Move Forward | W | W | Movement |
Next I created a struct for my datatable in my HUD header class in C++. Make sure to add the following namespace
"Runtime/Engine/Classes/Engine/DataTable.h" in the header class.
Code:
USTRUCT(Blueprintable) struct FKeyBoardBindingTable : public FTableRowBase { GENERATED_USTRUCT_BODY() UPROPERTY(BlueprintReadOnly, Category = "KeyBinding") FString Action; UPROPERTY(BlueprintReadOnly, Category = "KeyBinding") FString DefaultInput; UPROPERTY(BlueprintReadOnly, Category = "KeyBinding") FString Input; UPROPERTY(BlueprintReadOnly, Category = "KeyBinding") FString Category; };
Code:
UDataTable* KeyBoardBindingTable;
Code:
static ConstructorHelpers::FObjectFinder<UDataTable> KeyBoardBindingTable_BP(TEXT("DataTable'/Game/DataTables/KeyboardConfig.KeyboardConfig'")); KeyBoardBindingTable = KeyBoardBindingTable_BP.Object;
Then , I created userinterface class for keyboard configuration menu. , deriving from SCompounWidget , and wrote the UI in slate architecture. The UI is simple key customization UI that you can see in any game , when user clicks on an input , it asks you to bind it to a new value , then you have to press a key to bind to it. See below.
Code:
BEGIN_SLATE_FUNCTION_BUILD_OPTIMIZATION void SKeyConfigUI::Construct(const FArguments& InArgs) { GameHUD = InArgs._GameHUD; MenuStyle = &FMenuStyles::Get().GetWidgetStyle<FGlobalStyle>("Global"); ChildSlot.Padding(50 , 10) [ SNew(SOverlay) + SOverlay::Slot() .HAlign(HAlign_Fill) .VAlign(VAlign_Fill) .Padding(40) [ SNew(SBorder) .ColorAndOpacity(FLinearColor::White) .BorderImage(&MenuStyle->BorderBrush1) .Content() [ SNew(SOverlay) + SOverlay::Slot() .HAlign(HAlign_Fill) .VAlign(VAlign_Fill) [ SAssignNew(ParentWidget , SScrollBox) + SScrollBox::Slot() .HAlign(HAlign_Left) .Padding(40, 80, 0, 0) [ SNew(STextBlock) .Text(FText::FromString("KeyBoard Configuration")) .Font(FSlateFontInfo(FPaths::EngineContentDir() / TEXT("Slate/Fonts/jancient.ttf"), 30)) .ColorAndOpacity(FLinearColor(0.8, 0.7, 0.3, 1)) .ShadowColorAndOpacity(FLinearColor(0.16, 0.06, 0.05, 1)) ] + SScrollBox::Slot() .HAlign(HAlign_Fill) .Padding(40, 60, 40, 0) [ SNew(SHorizontalBox) + SHorizontalBox::Slot() .HAlign(HAlign_Fill) .VAlign(VAlign_Top) [ SAssignNew(GeneralButton, SButton) .ButtonStyle(&MenuStyle->KeyConfigHeaderStyle) .ContentPadding(2) .HAlign(HAlign_Center) .VAlign(VAlign_Top) .Content() [ SAssignNew(GeneralText, STextBlock) .Text(FText::FromString("General")) .Font(FSlateFontInfo(FPaths::EngineContentDir() / TEXT("Slate/Fonts/Roboto-Bold.ttf"), 15)) .ColorAndOpacity(FLinearColor(0.1, 0.1, 0.03, 1)) .ShadowColorAndOpacity(FLinearColor(0.93, 1, 0.6, 1)) .ShadowOffset(FVector2D(1, 1)) ] .OnClicked(this, &SKeyConfigUI::InputCaterGoryButonClicked, FString("General")) ] + SHorizontalBox::Slot() .HAlign(HAlign_Fill) .VAlign(VAlign_Top) [ SAssignNew(MovementButton, SButton) .ButtonStyle(&MenuStyle->KeyConfigNotSelectedStyle) .ContentPadding(2) .HAlign(HAlign_Center) .VAlign(VAlign_Top) .Content() [ SAssignNew(MovementText, STextBlock) .Text(FText::FromString("Movement")) .Font(FSlateFontInfo(FPaths::EngineContentDir() / TEXT("Slate/Fonts/Roboto-Bold.ttf"), 15)) .ColorAndOpacity(FLinearColor(0.12, 0.1, 0.03, 1)) .ShadowColorAndOpacity(FLinearColor(0.93, 1, 0.6, 1)) .ShadowOffset(FVector2D(1, 1)) ] .OnClicked(this, &SKeyConfigUI::InputCaterGoryButonClicked, FString("Movement")) ] + SHorizontalBox::Slot() .HAlign(HAlign_Fill) .VAlign(VAlign_Top) [ SAssignNew(CombatButton, SButton) .ButtonStyle(&MenuStyle->KeyConfigNotSelectedStyle) .ContentPadding(2) .HAlign(HAlign_Center) .VAlign(VAlign_Top) .Content() [ SAssignNew(CombatText, STextBlock) .Text(FText::FromString("Combat")) .Font(FSlateFontInfo(FPaths::EngineContentDir() / TEXT("Slate/Fonts/Roboto-Bold.ttf"), 15)) .ColorAndOpacity(FLinearColor(0.12, 0.1, 0.03, 1)) .ShadowColorAndOpacity(FLinearColor(0.93, 1, 0.6, 1)) .ShadowOffset(FVector2D(1, 1)) ] .OnClicked(this, &SKeyConfigUI::InputCaterGoryButonClicked, FString("Combat")) ] + SHorizontalBox::Slot() .HAlign(HAlign_Fill) .VAlign(VAlign_Top) [ SAssignNew(MiscellaneousButton, SButton) .ButtonStyle(&MenuStyle->KeyConfigNotSelectedStyle) .ContentPadding(2) .HAlign(HAlign_Center) .VAlign(VAlign_Top) .Content() [ SAssignNew(MiscellaneousText, STextBlock) .Text(FText::FromString("Miscellaneous")) .Font(FSlateFontInfo(FPaths::EngineContentDir() / TEXT("Slate/Fonts/Roboto-Bold.ttf"), 15)) .ColorAndOpacity(FLinearColor(0.12, 0.1, 0.03, 1)) .ShadowColorAndOpacity(FLinearColor(0.93, 1, 0.6, 1)) .ShadowOffset(FVector2D(1, 1)) ] .OnClicked(this, &SKeyConfigUI::InputCaterGoryButonClicked, FString("Miscellaneous")) ] ] ] + SOverlay::Slot() .HAlign(HAlign_Fill) .VAlign(VAlign_Fill) .Padding(FMargin(100, 250, 0, 50)) [ SNew(SScrollBox) + SScrollBox::Slot() .HAlign(HAlign_Fill) [ SAssignNew(KeyBindingWidget, SWidgetSwitcher) + SWidgetSwitcher::Slot() .HAlign(HAlign_Fill) .VAlign(VAlign_Top) [ SAssignNew(GeneralWidget, SScrollBox) ] + SWidgetSwitcher::Slot() .HAlign(HAlign_Fill) .VAlign(VAlign_Top) [ SAssignNew(MovementWidget, SScrollBox) ] + SWidgetSwitcher::Slot() .HAlign(HAlign_Fill) .VAlign(VAlign_Top) [ SAssignNew(CombatWidget, SScrollBox) ] + SWidgetSwitcher::Slot() .HAlign(HAlign_Fill) .VAlign(VAlign_Top) [ SAssignNew(MiscellaneousWidget, SScrollBox) ] ] ] + SOverlay::Slot() .HAlign(HAlign_Center) .VAlign(VAlign_Bottom) .Padding(10) [ SNew(SHorizontalBox) + SHorizontalBox::Slot() .HAlign(HAlign_Fill) .VAlign(VAlign_Fill) .Padding(10, 0) [ SNew(SButton) .ButtonStyle(&MenuStyle->GeneralButtonStyle1) .ContentPadding(2) .HAlign(HAlign_Fill) .VAlign(VAlign_Fill) .Content() [ SNew(STextBlock) .Text(FText::FromString(" Cancel ")) .Font(FSlateFontInfo(FPaths::EngineContentDir() / TEXT("Slate/Fonts/Roboto-Bold.ttf"), 15)) .ColorAndOpacity(FLinearColor(0.7, 0.6, 0.1, 1)) ] .OnClicked(this, &SKeyConfigUI::CancelButtonClicked) ] + SHorizontalBox::Slot() .HAlign(HAlign_Fill) .VAlign(VAlign_Center) .Padding(10, 0) [ SNew(SButton) .ButtonStyle(&MenuStyle->GeneralButtonStyle1) .ContentPadding(2) .HAlign(HAlign_Fill) .VAlign(VAlign_Fill) .Content() [ SNew(STextBlock) .Text(FText::FromString(" Save ")) .Font(FSlateFontInfo(FPaths::EngineContentDir() / TEXT("Slate/Fonts/Roboto-Bold.ttf"), 15)) .ColorAndOpacity(FLinearColor(0.7, 0.6, 0.1, 1)) ] .OnClicked(this, &SKeyConfigUI::SaveButtonClicked) ] + SHorizontalBox::Slot() .HAlign(HAlign_Fill) .VAlign(VAlign_Center) .Padding(10, 0) [ SNew(SButton) .ButtonStyle(&MenuStyle->GeneralButtonStyle1) .ContentPadding(2) .HAlign(HAlign_Center) .VAlign(VAlign_Center) .Content() [ SNew(STextBlock) .Text(FText::FromString(" Reset ")) .Font(FSlateFontInfo(FPaths::EngineContentDir() / TEXT("Slate/Fonts/Roboto-Bold.ttf"), 15)) .ColorAndOpacity(FLinearColor(0.7, 0.6, 0.1, 1)) ] .OnClicked(this, &SKeyConfigUI::ResetButtonClicked) ] ] ] ] ]; DrawKeyBindingWidget(); } END_SLATE_FUNCTION_BUILD_OPTIMIZATION void SKeyConfigUI::DrawKeyBindingWidget() { int32 rowindex = 1; GeneralWidget->ClearChildren(); MovementWidget->ClearChildren(); CombatWidget->ClearChildren(); MiscellaneousWidget->ClearChildren(); while (true) { FKeyBoardBindingTable* LookUpRow = GameHUD->KeyBoardBindingTable->FindRow<FKeyBoardBindingTable>(FName(*FString::FromInt(rowindex)), TEXT("Look Up")); if (LookUpRow) { if (LookUpRow->Category == "General") { GeneralIndex++; GeneralWidget->AddSlot().HAlign(HAlign_Fill).Padding(10) [ DrawKeyBindingWidgetRow(LookUpRow->Action, LookUpRow->Input, LookUpRow->Category, rowindex).ToSharedRef() ]; } else if (LookUpRow->Category == "Movement") { MovementIndex++; MovementWidget->AddSlot().HAlign(HAlign_Fill).Padding(10) [ DrawKeyBindingWidgetRow(LookUpRow->Action, LookUpRow->Input, LookUpRow->Category, rowindex).ToSharedRef() ]; } else if (LookUpRow->Category == "Combat") { CombatIndex++; CombatWidget->AddSlot().HAlign(HAlign_Fill).Padding(10) [ DrawKeyBindingWidgetRow(LookUpRow->Action, LookUpRow->Input, LookUpRow->Category, rowindex).ToSharedRef() ]; } else if (LookUpRow->Category == "Miscellaneous") { MiscellaneousIndex++; MiscellaneousWidget->AddSlot().HAlign(HAlign_Fill).Padding(10) [ DrawKeyBindingWidgetRow(LookUpRow->Action, LookUpRow->Input, LookUpRow->Category, rowindex).ToSharedRef() ]; } rowindex++; } else { break; } } } TSharedPtr<class SHorizontalBox> SKeyConfigUI::DrawKeyBindingWidgetRow(FString Action, FString Input, FString Category , int32 Index) { return SNew(SHorizontalBox) + SHorizontalBox::Slot().HAlign(HAlign_Center).VAlign(VAlign_Center) [ SAssignNew(BindingText, STextBlock).Text(FText::FromString(Action)) .Font(FSlateFontInfo(FPaths::EngineContentDir() / TEXT("Slate/Fonts/jancient.ttf"), 15)) .ColorAndOpacity(FLinearColor(0.8, 0.7, 0.3, 1)) .ShadowColorAndOpacity(FLinearColor(0.93, 1, 0.6, 1)) ] + SHorizontalBox::Slot().HAlign(HAlign_Fill).VAlign(VAlign_Fill) [ SAssignNew(BindingButton, SButton).ButtonStyle(&MenuStyle->KeyBindingButtonStyle).HAlign(HAlign_Center).VAlign(VAlign_Center) .Content() [ SAssignNew(BindingText, STextBlock).Text(FText::FromString(Input)) .Font(FSlateFontInfo(FPaths::EngineContentDir() / TEXT("Slate/Fonts/jancient.ttf"), 15)) .ColorAndOpacity(FLinearColor(0.8, 0.7, 0.3, 1)) .ShadowColorAndOpacity(FLinearColor(0.93, 1, 0.6, 1)) ] .OnClicked(this, &SKeyConfigUI::KeyCustomizationButtonClicked, FString(Action), FString(Input) , Index) ]; } FReply SKeyConfigUI::SaveButtonClicked() { int32 rowindex; for (rowindex = 1; rowindex < TempIndex.Num(); rowindex++) { FKeyBoardBindingTable* LookUpRow = GameHUD->KeyBoardBindingTable->FindRow<FKeyBoardBindingTable>(FName(*TempIndex[rowindex]), TEXT("Look Up")); if (LookUpRow) { LookUpRow->Input = TempInput[rowindex]; } else { break; } } return FReply::Handled(); } FReply SKeyConfigUI::CancelButtonClicked() { DrawKeyBindingWidget(); return FReply::Handled(); } FReply SKeyConfigUI::ResetButtonClicked() { int32 rowindex = 1; while (true) { FKeyBoardBindingTable* LookUpRow = GameHUD->KeyBoardBindingTable->FindRow<FKeyBoardBindingTable>(FName(*FString::FromInt(rowindex)), TEXT("Look Up")); if (LookUpRow) { LookUpRow->Input = LookUpRow->DefaultInput; DrawKeyBindingWidget(); rowindex++; } else { break; } } return FReply::Handled(); } FReply SKeyConfigUI::InputCaterGoryButonClicked(FString Category) { if (Category == "General") { GeneralButton->SetButtonStyle(&MenuStyle->KeyConfigHeaderStyle); MovementButton->SetButtonStyle(&MenuStyle->KeyConfigNotSelectedStyle); CombatButton->SetButtonStyle(&MenuStyle->KeyConfigNotSelectedStyle); MiscellaneousButton->SetButtonStyle(&MenuStyle->KeyConfigNotSelectedStyle); KeyBindingWidget->SetActiveWidgetIndex(0); } else if (Category == "Movement") { GeneralButton->SetButtonStyle(&MenuStyle->KeyConfigNotSelectedStyle); MovementButton->SetButtonStyle(&MenuStyle->KeyConfigHeaderStyle); CombatButton->SetButtonStyle(&MenuStyle->KeyConfigNotSelectedStyle); MiscellaneousButton->SetButtonStyle(&MenuStyle->KeyConfigNotSelectedStyle); KeyBindingWidget->SetActiveWidgetIndex(1); } else if (Category == "Combat") { GeneralButton->SetButtonStyle(&MenuStyle->KeyConfigNotSelectedStyle); MovementButton->SetButtonStyle(&MenuStyle->KeyConfigNotSelectedStyle); CombatButton->SetButtonStyle(&MenuStyle->KeyConfigHeaderStyle); MiscellaneousButton->SetButtonStyle(&MenuStyle->KeyConfigNotSelectedStyle); KeyBindingWidget->SetActiveWidgetIndex(2); } else if (Category == "Miscellaneous") { GeneralButton->SetButtonStyle(&MenuStyle->KeyConfigNotSelectedStyle); MovementButton->SetButtonStyle(&MenuStyle->KeyConfigNotSelectedStyle); CombatButton->SetButtonStyle(&MenuStyle->KeyConfigNotSelectedStyle); MiscellaneousButton->SetButtonStyle(&MenuStyle->KeyConfigHeaderStyle); KeyBindingWidget->SetActiveWidgetIndex(3); TSharedPtr<class SWidget> border = SNew(SCanvas); } return FReply::Handled(); } FReply SKeyConfigUI::KeyCustomizationButtonClicked(FString Key, FString Value , int32 Index) { Selectedkey = Key; SelectedOldValue = Value; SelectedIndex = Index-1; CustomKeyWidget = SNew(SOverlay) + SOverlay::Slot() .HAlign(HAlign_Fill) .VAlign(VAlign_Fill).Padding(400) [ SNew(SBorder) .BorderImage(&MenuStyle->BorderBrush2) .VAlign(VAlign_Center) .Content() [ SNew(SScrollBox) + SScrollBox::Slot() .HAlign(HAlign_Center) [ SNew(STextBlock) .Text(FText::FromString("Press any key to map to")) .Font(FSlateFontInfo(FPaths::EngineContentDir() / TEXT("Slate/Fonts/Roboto-Bold.ttf"), 15)) .ColorAndOpacity(FLinearColor(0.7, 0.6, 0.1, 1)) ] + SScrollBox::Slot() .HAlign(HAlign_Center) [ SNew(STextBlock) .Text(FText::FromString(Key)) .Font(FSlateFontInfo(FPaths::EngineContentDir() / TEXT("Slate/Fonts/Roboto-Bold.ttf"), 17)) .ColorAndOpacity(FLinearColor(0.46, 0.77, 0.73, 1)) ] + SScrollBox::Slot() .HAlign(HAlign_Center) [ SNew(STextBlock) .Text(FText::FromString("Press ESC to cancel")) .Font(FSlateFontInfo(FPaths::EngineContentDir() / TEXT("Slate/Fonts/Roboto-Bold.ttf"), 15)) .ColorAndOpacity(FLinearColor(0.46, 0.77, 0.73, 1)) .ColorAndOpacity(FLinearColor(0.7, 0.6, 0.1, 1)) ] ] ]; GEngine->GameViewport->AddViewportWidgetContent(CustomKeyWidget.ToSharedRef()); KeyBindingWidget->SetEnabled(false); ParentWidget->SetEnabled(false); return FReply::Handled(); } FReply SKeyConfigUI::OnKeyDown(const FGeometry& MyGeometry, const FKeyboardEvent& InKeyboardEvent) { GEngine->GameViewport->RemoveViewportWidgetContent(CustomKeyWidget.ToSharedRef()); if (InKeyboardEvent.GetKey() == EKeys::Escape) { KeyBindingWidget->SetEnabled(true); ParentWidget->SetEnabled(true); } else { NewKey = InKeyboardEvent.GetKey(); KeyBindingWidget->SetEnabled(true); ParentWidget->SetEnabled(true); FKeyBoardBindingTable* LookUpRow = GameHUD->KeyBoardBindingTable->FindRow<FKeyBoardBindingTable>(*FString::FromInt(SelectedIndex+1), TEXT("Look Up")); int32 widgetIndex; if (NewKey != FKey(FName(*LookUpRow->Input))) { TempIndex.Add(FString::FromInt(SelectedIndex + 1)); TempInput.Add(NewKey.ToString()); int index =KeyBindingWidget->GetActiveWidgetIndex(); switch (index) { case 0: GeneralWidget->RemoveSlot(SelectedIndex); GeneralWidget->InsertSlot(SelectedIndex).HAlign(HAlign_Fill).Padding(10) [ DrawKeyBindingWidgetRow(LookUpRow->Action, NewKey.ToString(), LookUpRow->Category, SelectedIndex + 1).ToSharedRef() ]; break; case 1: widgetIndex = SelectedIndex - GeneralIndex; MovementWidget->RemoveSlot(widgetIndex); MovementWidget->InsertSlot(widgetIndex).HAlign(HAlign_Fill).Padding(10) [ DrawKeyBindingWidgetRow(LookUpRow->Action, NewKey.ToString(), LookUpRow->Category, SelectedIndex + 1).ToSharedRef() ]; break; case 2: widgetIndex = SelectedIndex - GeneralIndex - MovementIndex; CombatWidget->RemoveSlot(widgetIndex); CombatWidget->InsertSlot(widgetIndex).HAlign(HAlign_Fill).Padding(10) [ DrawKeyBindingWidgetRow(LookUpRow->Action, NewKey.ToString(), LookUpRow->Category, SelectedIndex + 1).ToSharedRef() ]; break; case 3: widgetIndex = SelectedIndex - GeneralIndex - MovementIndex - CombatIndex; MiscellaneousWidget->RemoveSlot(widgetIndex); MiscellaneousWidget->InsertSlot(widgetIndex).HAlign(HAlign_Fill).Padding(10) [ DrawKeyBindingWidgetRow(LookUpRow->Action, NewKey.ToString(), LookUpRow->Category, SelectedIndex + 1).ToSharedRef() ]; break; default: break; } } } return FReply::Handled(); }
Code:
class FORGOTTENLEGION_API SKeyConfigUI : public SCompoundWidget { SLATE_BEGIN_ARGS(SKeyConfigUI) { } SLATE_ARGUMENT(TWeakObjectPtr<class AGameHUD>, GameHUD); SLATE_END_ARGS() public: /** Constructs this widget with InArgs */ void Construct(const FArguments& InArgs); bool FileIO__SaveStringTextToFile(FString SaveDirectory, FString FileName, FString SaveText, bool AllowOverWriting); bool FileIO_ReadFileToString(FString FileDirectory, FString FilePath); /** Overridden from SWidget: Called when a key is pressed down - capturing copy */ virtual FReply OnKeyDown(const FGeometry& MyGeometry, const FKeyboardEvent& InKeyboardEvent) override; private: SScrollBox::FSlot& InsertSlot(int32 Index); FReply InputCaterGoryButonClicked(FString Category); TSharedPtr<class SHorizontalBox> DrawKeyBindingWidgetRow(FString Action, FString Input, FString Category , int32 Index); void DrawKeyBindingWidget(); const struct FGlobalStyle* MenuStyle; FReply SaveButtonClicked(); FReply CancelButtonClicked(); FReply ResetButtonClicked(); FReply KeyCustomizationButtonClicked(FString Key, FString Value , int32 Index); TWeakObjectPtr<class AGameHUD> GameHUD; TSharedPtr<class SWidgetSwitcher> KeyBindingWidget = SNew(SWidgetSwitcher); TSharedRef<FSlateGameResources> SlateResources = FSlateGameResources::New(FName("BorderBrush1"), "/Game/Blueprints/Widgets/Styles", "/Game/Blueprints/Widgets/Styles"); FSlateGameResources& Style = SlateResources.Get(); const FSlateBrush* BorderBrush1 = Style.GetBrush("BorderBrush1"); FLinearColor SelectedButtonColor = FLinearColor(0.58, 0.74, 0.89, 1); FString Selectedkey; FString SelectedOldValue; int32 SelectedIndex; int32 GeneralIndex = 0;; int32 MovementIndex = 0; int32 CombatIndex = 0; int32 MiscellaneousIndex = 0; TArray<FString> TempIndex; TArray<FString> TempInput; FKey NewKey; TSharedPtr<class SButton> GeneralButton = SNew(SButton); TSharedPtr<class SButton> MovementButton = SNew(SButton); TSharedPtr<class SButton> CombatButton = SNew(SButton); TSharedPtr<class SButton> MiscellaneousButton = SNew(SButton); TSharedPtr<class STextBlock> GeneralText = SNew(STextBlock); TSharedPtr<class STextBlock> MovementText = SNew(STextBlock); TSharedPtr<class STextBlock> CombatText = SNew(STextBlock); TSharedPtr<class STextBlock> MiscellaneousText = SNew(STextBlock); TSharedPtr<class SScrollBox> ParentWidget = SNew(SScrollBox); TSharedPtr<class SScrollBox> GeneralWidget = SNew(SScrollBox); TSharedPtr<class SScrollBox> MovementWidget = SNew(SScrollBox); TSharedPtr<class SScrollBox> CombatWidget = SNew(SScrollBox); TSharedPtr<class SScrollBox> MiscellaneousWidget = SNew(SScrollBox); TSharedPtr<class STextBlock> BindingText = SNew(STextBlock); TSharedPtr<class SButton> BindingButton = SNew(SButton); TSharedPtr<class SOverlay> CustomKeyWidget = SNew(SOverlay); };
Code:
SAssignNew(KeyConfigUI, SKeyConfigUI).GameHUD(this); if (GEngine && GEngine->GameViewport) { Viewport = GEngine->GameViewport; Viewport->AddViewportWidgetContent( SNew(SWeakWidget).PossiblyNullContent(KeyConfigUI.ToSharedRef()) ); }
Code:
#include "Runtime/Engine/Classes/GameFramework/PlayerInput.h" #include "Runtime/Engine/Classes/GameFramework/InputSettings.h" #include "Runtime/CoreUObject/Public/UObject/UObjectGlobals.h"
Code:
void AForgottenLegionCharacter::SetupPlayerInputComponent(class UInputComponent* InputComponent) { // Set up gameplay key bindings check(InputComponent); const UInputSettings* InputSettings = GetDefault<UInputSettings>(); int rowindex = 1; while (true) { FKeyBoardBindingTable* LookUpRow = KeyBoardBindingTable->FindRow<FKeyBoardBindingTable>(FName(*FString::FromInt(rowindex)), TEXT("Look Up")); if (LookUpRow) { if (LookUpRow->Action == "Move Forward") { const FInputAxisKeyMapping axismapping(FName("Move Forward"), FKey(FName(*LookUpRow->Input)) , 1); ((UInputSettings*)InputSettings)->AddAxisMapping(axismapping); } else if (LookUpRow->Action == "Move Backward") { const FInputAxisKeyMapping axismapping(FName("Move Forward"), FKey(FName(*LookUpRow->Input)), -1); ((UInputSettings*)InputSettings)->AddAxisMapping(axismapping); } else if (LookUpRow->Action == "Move Left") { const FInputAxisKeyMapping axismapping(FName("Move Right"), FKey(FName(*LookUpRow->Input)), -1); ((UInputSettings*)InputSettings)->AddAxisMapping(axismapping); } else if (LookUpRow->Action == "Move Right") { const FInputAxisKeyMapping axismapping(FName("Move Right"), FKey(FName(*LookUpRow->Input)), 1); ((UInputSettings*)InputSettings)->AddAxisMapping(axismapping); } else { const FInputActionKeyMapping actionmapping(FName(*LookUpRow->Action), FKey(FName(*LookUpRow->Input)), false , false , false , false); ((UInputSettings*)InputSettings)->AddActionMapping(actionmapping); } rowindex++; } else { break; } } const FInputAxisKeyMapping turnaxismapping(FName("Turn"), FKey(FName("MouseX")), 1); ((UInputSettings*)InputSettings)->AddAxisMapping(turnaxismapping); const FInputAxisKeyMapping lookupaxismapping(FName("LookUp"), FKey(FName("MouseY")), 1); ((UInputSettings*)InputSettings)->AddAxisMapping(lookupaxismapping); ((UInputSettings*)InputSettings)->SaveKeyMappings(); InputComponent->BindAction("Jump", IE_Pressed, this, &ACharacter::Jump); InputComponent->BindAxis("Move Forward", this, &AForgottenLegionCharacter::MoveForward); InputComponent->BindAxis("Move Right", this, &AForgottenLegionCharacter::MoveRight); InputComponent->BindAxis("Turn", this, &APawn::AddControllerYawInput); InputComponent->BindAxis("LookUp", this, &APawn::AddControllerPitchInput); }
Thanks and Regards ,
Sameek Kundu
Comment