How do you smooth the transition for the camera during crouching

I’m trying to figure out the best way to smooth the camera when the crouch input is pressed/released. Using the building ACharacter::Crouch() it just jumps to the position. I’m trying to add my own crouch logic instead:

void AMyCharacter::StartCrouch() {
	bIsCrouching = true;	
	bCrouchProgress = true;
}
void AMyCharacter::Tick(float DeltaSeconds) 
{
	Super::Tick(DeltaSeconds);
	FVector currentCameraPos = FollowCamera->RelativeLocation;
	if (bIsCrouching && bCrouchProgress == true) {
		currentCameraPos = FMath::VInterpTo(FVector(0.0, 0.0, 0.0), FVector(0.0, 0.0, -32), DeltaSeconds, 0.5f);
		FollowCamera->SetRelativeLocation(currentCameraPos);
	}
	else {
		currentCameraPos = FMath::VInterpTo(FVector(0.0, 0.0, -32), FVector(0.0, 0.0, 0.0), DeltaSeconds, 0.5f);
		FollowCamera->SetRelativeLocation(currentCameraPos);
	}
	if (currentCameraPos.Z > CrouchedEyeHeight) {
		bCrouchProgress = false;
	}
}

I can’t seem to get the VinterpTo to work correctly. Any Help is appreciated.

I suggest you use Lerp.

Totally untested code below that I wrote here in text of how I would do it.

float CrouchProgress = 0;

void AMyCharacter::StartCrouch() {
     bIsCrouching = true;
}
void AMyCharacter::Tick(float DeltaSeconds) 
{
    Super::Tick(DeltaSeconds);
     
    float SecondsToCrouch = 0.3;
     
    FVector uncrouchedCameraPos = FVector(0.0, 0.0, 0.0);
    FVector crouchedCameraPos = FVector(0.0, 0.0, -32);
     
    if ((bIsCrouching && CrouchProgress > 0.0) || (bIsCrouching && CrouchProgress < 1.0)) {
        CrouchProgress = FMath::Clamp(CrouchProgress + (DeltaSeconds / SecondsToCrouch) * (bIsCrouching ? 1.0, -1.0), 0.0, 1.0);
         
        FVector currentCameraPos = FMath::Lerp(uncrouchedCameraPos, crouchedCameraPos, CrouchProgress);
        FollowCamera->SetRelativeLocation(currentCameraPos);
    }
}

Thanks this was almost perfect. Just had a couple of small fixes.
Final Code

 void AMyCharacter::Tick(float DeltaSeconds)
    {
    	Super::Tick(DeltaSeconds);
    
    	float SecondsToCrouch = .2;
    
    	FVector uncrouchedCameraPos = FVector(0.0, 0.0, 0.0);
    	FVector crouchedCameraPos = FVector(0.0, 0.0, -32);
    	FVector currentCameraPos = FollowCamera->RelativeLocation;
    	if ((!bIsCrouching && CrouchProgress > 0.0) || (bIsCrouching && CrouchProgress < 1.0)) {
    		CrouchProgress = FMath::Clamp(CrouchProgress + (DeltaSeconds / SecondsToCrouch) * (bIsCrouching ? 1.0 : -1.0), 0.0, 1.0);
    		currentCameraPos = FMath::Lerp(uncrouchedCameraPos, crouchedCameraPos, CrouchProgress);
    		FollowCamera->SetRelativeLocation(currentCameraPos);
    	}
    }

Out of curiosity is it best to change the actual camera location for a crouch, the CameraBoom or rather another component?

Cheers

Ah yes, I forgot the !bIsCrouching, other than that, you don’t need to add the

FVector currentCameraPos = FollowCamera->RelativeLocation;

Because you’re not using that value, you’re assigning it via the Lerp, you don’t care what the current value is.

To address your other question:

  • If you’re using a CameraBoom, then yes, I would change it’s location. If not, then this is a fine implementation.
  • You’ll especially want to use a CameraBoom if your camera is outside the player’s collision capsule.