Announcement

Collapse
No announcement yet.

Tutorial - How to dynamically bind input using C++

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • replied
    Thank you very much!

    Leave a comment:


  • replied
    Hi ,

    Sorry for not mentioning this , but insertslot and removeslot are my own functions , which are given as follows :

    SScrollBox.h

    SScrollBox::FSlot& InsertSlot(int32 Index);
    SScrollBox::FSlot& RemoveSlot(int32 Index);

    SScrollBox.cpp

    SScrollBox::FSlot& SScrollBox::InsertSlot(int32 Index)

    {

    SScrollBox::FSlot& NewSlot = SScrollBox::Slot();

    ScrollPanel->Children.Insert(&NewSlot , Index);


    return NewSlot;

    }

    SScrollBox::FSlot& RemoveSlot(int32 Index)
    {
    SScrollBox::FSlot& NewSlot = SScrollBox::Slot();
    ScrollPanel->Children.RemoveAt(Index);
    return NewSlot;
    }

    Leave a comment:


  • replied
    Thanks for the code and the time put into this document! There were a few things not mentioned so just to let you know. Please let me know if the references are incorrect.


    missing from hud
    -----------------------
    #include "Engine\GameViewportClient.h"


    UGameViewportClient* Viewport;
    SKeyConfigUI* KeyConfigUI; <<----- ?





    missing within KeyConfigUI.h
    ------------------------------
    #include "Slate.h"
    #include "SlateGameResources.h"
    #include "GlobalMenuStyle.h"
    #include "MenuStyles.h"



    The creation of the MenuStyles and GlobalStyle classes are not mentioned but the necessary code is @ http://minalien.com/unreal-engine-4-...slatec-part-2/



    Missing within GlobalMenuStyle.h
    ------------------------------------
    FButtonStyle KeyConfigNotSelectedStyle;
    FButtonStyle KeyConfigHeaderStyle;
    FButtonStyle KeyBindingButtonStyle;
    FButtonStyle GeneralButtonStyle1;

    FSlateBrush BorderBrush1;
    FSlateBrush BorderBrush2;




    Missing from Character
    --------------------------
    UDataTable* KeyBoardBindingTable;
    void MoveForward(float Val);
    void MoveRight(float Val)




    AddSlot and RemoveSlot takes type "const TSharedRef<SWidget>& " not an int32 .

    Thank you! I have gotten it to build although I haven't tested it's functionality yet.
    Last edited by Garner; 09-07-2014, 09:24 PM.

    Leave a comment:


  • replied
    Done. Didn't know this. Thanks

    Leave a comment:


  • replied
    Use code tag, it's impossible to read anything.

    Leave a comment:


  • started a topic Tutorial - How to dynamically bind input using C++

    Tutorial - How to dynamically bind input using C++

    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.
    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;
    
    };
    Now define your datatable in HUD header -
    Code:
    UDataTable* KeyBoardBindingTable;
    and initialize it the HUD constructor class
    Code:
    static ConstructorHelpers::FObjectFinder<UDataTable> KeyBoardBindingTable_BP(TEXT("DataTable'/Game/DataTables/KeyboardConfig.KeyboardConfig'"));
    	KeyBoardBindingTable = KeyBoardBindingTable_BP.Object;
    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.

    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();
    }
    OK , and the below is my header class , in case you are confused with the above code.

    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);
    	
    };
    Now you can easily add this UI in your viewport in your HUD class , whenever required , using the below line

    Code:
    SAssignNew(KeyConfigUI, SKeyConfigUI).GameHUD(this);
    	if (GEngine && GEngine->GameViewport)
    	{
    	     Viewport = GEngine->GameViewport;
    
    		Viewport->AddViewportWidgetContent(
    			SNew(SWeakWidget).PossiblyNullContent(KeyConfigUI.ToSharedRef())
    			);
    		}
    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

    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);
    
    	
    }
    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
    Last edited by sameek4; 11-24-2014, 02:39 AM.
Working...
X