Input Component can be used to Listen for an Input whether it be an Axis or an Action. You can simply bind your function to a specific Input:
class ABlogCharacter : public ACharacter
virtual void SetupPlayerInputComponent(class UInputComponent* PlayerInputComponent) override;
void ABlogCharacter::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent)
PlayerInputComponent->BindAction(“InventorySlotOne”, IE_Pressed, this, &ABlogCharacter::SwitchToInventorySlotOnePressed);PlayerInputComponent->BindAction(“InventorySlotTwo”, IE_Pressed, this, &ABlogCharacter::SwitchToInventorySlotTwoPressed);
The solution above works well and probably does the job for most of the scenarios where you would want to listen for an input.
Now Imagine a case where you have many more Inventory Slots or Actions and you wish to bind them to a key. Well if you want to follow the method mentioned above you would have bunch of functions for every Inventory Slot or for Every Action.
Well there are few ways you could achieve this without creating useless functions.
1- Declare a Delegate With the Variable Type in the header
DECLARE_DELEGATE_OneParam(FInputSwitchInventoryDelegate, const int32);
Here we are defining what our Action key should pass in when the Input is pressed. We use the int32 as an Index to our Inventory Slot. You could use any variable type.
2- Declare the Function which your Input should call.
UFUNCTION(BlueprintCallable, Category = "Inventory")
void SwitchToItem(const int32 InItemIndex);
3- Use the Delegate Overload of the Bind Action to Bind to the Same Function with Specific Input
PlayerInputComponent->BindAction<DelegateHere>(ActionName, Key Event, this, Function To call, Parameter);
So in our SetupPlayerInputComponent we can bind as follow:
PlayerInputComponent->BindAction<FInputSwitchInventoryDelegate>(“InventorySlotOne”, IE_Pressed, this, &ABlogCharacter::SwitchToItem, 1);PlayerInputComponent->BindAction<FInputSwitchInventoryDelegate>(“InventorySlotTwo”, IE_Pressed, this, &ABlogCharacter::SwitchToItem, 2);PlayerInputComponent->BindAction<FInputSwitchInventoryDelegate>(“InventorySlotThree”, IE_Pressed, this, &ABlogCharacter::SwitchToItem, 3);PlayerInputComponent->BindAction<FInputSwitchInventoryDelegate>(“InventorySlotFour”, IE_Pressed, this, &ABlogCharacter::SwitchToItem, 4);
As you can see we are using the Same function and we just pass in the different Item Index depending on what key is pressed. You can definitely expand on this by adding more parameters.
So now that we know how to use delegate to pass in variables, What if we want more control or customization over our bindings, Whether it should Consume the Input or Should it execute When the Game is Paused.
In order to bind with more config , we have to use a FInputActionbinding structure.
1- Prepare the structure
FInputActionBinding NewBinding= FInputActionBinding(KeyName,Key Event);NewBinding.bConsumeInput = true or false;
NewBinding.bExecuteWhenPaused = true or false;
NewBinding.KeyEvent = IE_Pressed or IE_Released ..;
Setting bConsumeInput to True will Consume the input and prevent it from passing to another component. This is useful when you want to allow the input to be passed to any inherited class
bExecuteWhenPaused Defines whether this input binding should be called when the game is paused
Key events are an enum of different events of a key/input such as “IE_Pressed” , “IE_Released”.
2- Add the Action Binding to Input Component
It’s Important to note that the Solutions above are also applicable to Axis bindings. You can use “FInputAxisBinding” to bind to an Axis input.
That’s all for now , I’ll be updating more methods to bind in near future.