The eye height issue when crouching and having the camera outside the capsule.

Hi. There is no mesh on the character, only the capsule and a camera located on the spring arm that is connected to a camera root scene component. I set the shrink value of the capsule by a ratio at the BeginPlay(), and the function below sets the CrouchedEyeHeight by a ratio of 0.8 with the default engine function.

void UCustomMovementComponent::BeginPlay()
{
	Super::BeginPlay();

	if (IsValid(CharacterOwner))
	{
		DefaultEyeHeight = CharacterOwner->BaseEyeHeight;
		StandingHalfHeight = CharacterOwner->GetCapsuleComponent()->GetUnscaledCapsuleHalfHeight();
		SetCrouchedHalfHeight(StandingHalfHeight * CrouchRatio);
		TargetHalfHeight = StandingHalfHeight;
	}
}

void UCharacterMovementComponent::SetCrouchedHalfHeight(const float NewValue)
{
	CrouchedHalfHeight = NewValue;

	if (CharacterOwner != nullptr)
	{
		CharacterOwner->RecalculateCrouchedEyeHeight();
	}
}

void ACharacter::RecalculateCrouchedEyeHeight()
{
	if (CharacterMovement != nullptr)
	{
		constexpr float EyeHeightRatio = 0.8f;
		CrouchedEyeHeight = CharacterMovement->GetCrouchedHalfHeight() * EyeHeightRatio;
	}
}

And with another function below I trigger crouching and do the corresponding value redirects.


void UCustomMovementComponent::ToggleCrouching(const bool bCrouch)
{
	if (IsValid(CharacterOwner) && !IsSprinting())
	{
		TargetHalfHeight = bCrouch ? GetCrouchedHalfHeight() : StandingHalfHeight;
		TargetEyeHeight = bCrouch ? CharacterOwner->CrouchedEyeHeight : DefaultEyeHeight;
	}
}

Then, the necessary interpolations are made in Tick() with the updated values.

void UCustomMovementComponent::TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction)
{
	Super::TickComponent(DeltaTime, TickType, ThisTickFunction);
	
	if (!IsValid(CharacterOwner)) return;
	if (UCapsuleComponent* capsule = CharacterOwner->GetCapsuleComponent())
	{
		CurrentHalfHeight = capsule->GetUnscaledCapsuleHalfHeight();

		if (FMath::Abs(CurrentHalfHeight - TargetHalfHeight) < 0.1f)
		{
			CurrentHalfHeight = TargetHalfHeight;
			capsule->SetCapsuleHalfHeight(TargetHalfHeight);
			CharacterOwner->BaseEyeHeight = TargetEyeHeight;
			return;
		}

		capsule->SetCapsuleHalfHeight(FMath::FInterpTo(CurrentHalfHeight, TargetHalfHeight, DeltaTime, CrouchInterpSpeed));
		CharacterOwner->BaseEyeHeight = FMath::FInterpTo(CharacterOwner->BaseEyeHeight, TargetEyeHeight, DeltaTime, CrouchInterpSpeed);
	}
}

The camera which initially remains inside the capsule, ends up outside the capsule, on top, when we crouch down. Even though it updates at the same ratio, I still don’t get the desired result. Also, setting the BaseEyeHeight value does not make any difference.
Am I making a logical mistake here, or is there something else preventing this?