Input Binding

As mentioned we're going to use Input Based attachment, so lets create two new Input Actions and link them in the Input Mapping Context (IMC_Default)

For this we'll need to keep track of the climb input state.

.h

// ZCCharacterMovementComponent.h

public:
	void WantsClimbing();
	void CancelClimbing();

private:
	bool bWantsToClimb = false;

.cpp

// ZCCharacterMovementComponent.cpp

void UZCCharacterMovementComponent::WantsClimbing()
{
	if (!bWantsToClimb)
	{
		bWantsToClimb = CanStartClimbing();
	}
}

void UZCCharacterMovementComponent::CancelClimbing()
{
	bWantsToClimb = false;
}

And llikewise hook up the input

.h

// ZCClimbingCharacter.h

public:
        UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = Input, meta = (AllowPrivateAccess = "true"))
        class UInputAction* ClimbAction;
        UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = Input, meta = (AllowPrivateAccess = "true"))
        class UInputAction* CancelClimbAction;

protected:
        void Climb(const FInputActionValue& Value);
        void CancelClimb(const FInputActionValue& Value);

.cpp

// ZCClimbingCharacter.cpp

void AZCClimbingCharacter::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent)
{
	Super::SetupPlayerInputComponent(PlayerInputComponent);

	if (UEnhancedInputComponent* EnhancedInputComponent = CastChecked<UEnhancedInputComponent>(PlayerInputComponent)) 
	{
		EnhancedInputComponent->BindAction(ClimbAction, ETriggerEvent::Triggered, this, &AZCClimbingCharacter::Climb);
		EnhancedInputComponent->BindAction(CancelClimbAction, ETriggerEvent::Triggered, this, &AZCClimbingCharacter::CancelClimb);
	}
}

void AZCClimbingCharacter::Climb(const FInputActionValue& Value)
{
	if (MovementComponent)
	{
		MovementComponent->WantsClimbing();
	}
}

void AZCClimbingCharacter::CancelClimb(const FInputActionValue& Value)
{
	if (MovementComponent)
	{
		MovementComponent->CancelClimbing();
	}
}

Then we can replace the check to CanStartClimbing() like so

.cpp

// ZCCharacterMovementComponent.cpp

void UZCCharacterMovementComponent::OnMovementUpdated(float DeltaSeconds, const FVector& OldLocation, const FVector& OldVelocity)
{
	if (bWantsToClimb)
	{
		SetMovementMode(EMovementMode::MOVE_Custom, ECustomMovementMode::CMOVE_Climbing);
	}
	
	Super::OnMovementUpdated(DeltaSeconds, OldLocation, OldVelocity);
}

Alright, now we've got the input settled, let's actually do something with it, like attaching to a wall!

Last updated