Toggle crouch using Enhanced Input

Hey. I’ve been trying to make crouch action for my character using enhanced input (first time using enhanced input).
I’ve programmed crouch function which works only when I hold crouch button. However I am struggling to program toggle function, it works like previously mentioned crouch function.

In PlayerCharacterController.cpp:

  • HandleCrouchToggle definition

bIsCrouching is set to “false” in PlayerCharacter’s constructor.

void APlayerCharacterController::HandleCrouchToggle()
{
	if (PlayerCharacter)
	{
		if (!(PlayerCharacter->bIsCrouching))
		{
			PlayerCharacter->Crouch();
			PlayerCharacter->bIsCrouching = true;
		}
		else
		{
			PlayerCharacter->UnCrouch();
			PlayerCharacter->bIsCrouching = false;
		}
	}
}
  • Binding InputAction
EnhancedInputComponent->BindAction(ActionCrouch, ETriggerEvent::Started, this, &APlayerCharacterController::HandleCrouchToggle);

InputAction for CrouchToggle

IA_CrouchToggle in Input Mapping Context

IA_CrouchToggle is selectable in BP_PlayerCharacterController

It’s hard to tell what is wrong, but I can see three things that look off.

  1. I’m fairly sure you shouldn’t be setting PlayerCharacter->bIsCrouching directly. The Crouch function should be enough. bIsCrouching is used for a lot of things internally and is set internally as well. There’s a reason it is set as BlueprintReadOnly.

  2. Also, using ETriggerEvent::Started probably isn’t right either and you should be using ETriggerEvent::Triggered

  3. I noticed that your InputAction “IA_CrouchToggle” doesn’t have any triggers set. I would add Pressed to the array.

Rather than using PlayerCharacter->bIsCrouching to check the current state of the character, I would use your own boolean that only you can set. Then you can be sure that the toggle is controlled by you.

I think by bIsCrouching you actually meant bIsCrouched which is inherited from ACharacter class, bIsCrouching has been declared and defined by me.
Anyway I’ve got rid of bIsCrouching and used bIsCrouched instead. I’ve also added bToggleCrouch variable to PlayerCharacter class to switch between crouch options in blueprint for my character. Based on this variable I’ve done to ways of binding crouch action. I haven’t added any modifiers to IA_CrouchToggle too.

PlayerCharacterController.cpp

  • ActionCrouch bindings
// Crouch Action
if (PlayerCharacter->bToggleCrouch)
{
	EnhancedInputComponent->BindAction(ActionCrouch, ETriggerEvent::Started, this, &APlayerCharacterController::HandleCrouchToggle);
}
else
{
	EnhancedInputComponent->BindAction(ActionCrouch, ETriggerEvent::Triggered, this, &APlayerCharacterController::HandleCrouch);
	EnhancedInputComponent->BindAction(ActionCrouch, ETriggerEvent::Completed, this, &APlayerCharacterController::HandleUnCrouch);
}
  • Handlers’ definitions
void APlayerCharacterController::HandleCrouch()
{
	if (PlayerCharacter)
	{
		PlayerCharacter->Crouch();
	}
}
void APlayerCharacterController::HandleUnCrouch()
{
	if (PlayerCharacter)
	{
		PlayerCharacter->UnCrouch();
	}
}

void APlayerCharacterController::HandleCrouchToggle()
{
	if (PlayerCharacter)					
	{
		if (PlayerCharacter->bIsCrouched)
		{
			PlayerCharacter->UnCrouch();
		}
		else
		{
			PlayerCharacter->Crouch();
		}
	}
}

Crouch() and UnCrouch() functions switch bIsCrouched in theirs definitions.

I believe this is not the most efficient way to implement this functionality, so I look forward for any suggestions.