UInputComponent BindAction variadic

Hi, I’m trying to bind input to my pawn and following along a tutorial I use:

   // get input component
	inputComponent = GetOwner()->FindComponentByClass<UInputComponent>();
	if (inputComponent)
	{
		UE_LOG(LogTemp, Warning, TEXT("input component present in %s."), *GetOwner()->GetName())
		
		inputComponent->BindAction("grab", EInputEvent::IE_Pressed, this, &UGrabber::Grab);
	}
	else
		UE_LOG(LogTemp, Error, TEXT("input component missing in %s."), *GetOwner()->GetName())

I noticed that BindAction has a variadic overload that takes parameters, so I guessed it allows me to pass parameter to a delegate:

typedef void(UGrabber::*Delegate)(int);
    		inputComponent->BindAction<Delegate, UGrabber>("grab", EInputEvent::IE_Pressed, this, &UGrabber::GrabWithParams, 10);   // this doesn't work

it needs the call signature of the delegate, but this does not compile. Why?

The reason that your function doesn’t work out of the box is that the function signature has to be defined. Note that the variadic variant of this function also requires a template type Delegate.

If you look at the InputComponent header you’ll find that the full signature of the non-variadic version looks like this.

template< class UserClass > FInputActionBinding& BindAction( const FName ActionName, const EInputEvent KeyEvent, UserClass* Object, typename FInputActionHandlerSignature::TUObjectMethodDelegate< UserClass >::FMethodPtr Func )

Note the “typename FInputActionHandlerSignature” part. This is a typedef for TDelegate

The variadic version looks like this:

template< class DelegateType, class UserClass, typename… VarTypes >
FInputActionBinding& BindAction( const FName ActionName, const EInputEvent KeyEvent, UserClass* Object, typename DelegateType::template TUObjectMethodDelegate< UserClass >::FMethodPtr Func, VarTypes… Vars )

It expects a type that has a template member with the name TUObjectMethodDelegate. Although you could make your class that has such a member template, in most every case you’d want to call the variadic version like so:

InputComponent->BindAction < TDelegate < void(int) >, UGrabber >(TEXT("Grab"), EInputEvent::IE_Pressed, this, &UGrabber::Grab, 10);

Your question is almost two years old, but who knows, maybe it’s still useful to you. I hope it will at least be for the next visitors with the same question.

1 Like