Smooth crouching replication

Hey all, what would be the best way to add a smooth crouching system that’s replicated. I’ve tried this with timelines but I just get stuttering on the client.

Are you using the default character class (character movement component)? If so, it has built -in crouch/un-crouch networked functionality.

Otherwise show your code (BP/C++). Can’t help unless we see what you’re doing.

Only replicate the state crouched/uncrouched like in the default character class. Don’t replicate the movement.

React on the replicated state change and start the animation of crouching/uncrouching on every client on its own.

2 Likes

This is old but… what i did was to handled the local smotheness of the Camera container with a FTimeline.

When a press crouch im call the native character crouch and then run the timeline ONLY on local player and with a simple compensation system got the smoothness for the FPS Local camera (im not using Spring arms to keep inmediatly response on inputs)

*Setup required values

	StandingCapsuleHeight = Character->GetCapsuleComponent()->GetScaledCapsuleHalfHeight();
		CrouchingCapsuleHeight = StandingCapsuleHeight * CrouchHeightScale;
  • Get the relative camera location
FVector USlideCrouchComponent::GetRelativeCameraLocationOnCrouch(const float& Alpha) const
{
	float CameraRelativeLocationZ;
	const float DiffZPosition = StandingCapsuleHeight - CrouchingCapsuleHeight;

	if (Character->GetGroundMovement() == EGroundMovement::Standing)
	{
		// On Uncrouching
		CameraRelativeLocationZ = FMath::Lerp(
			CameraRelativeLocation.Z, // to this
			CameraRelativeLocation.Z - DiffZPosition, // from this
			Alpha
		);
	}
	else
	{
		// On Crouching or slide
		CameraRelativeLocationZ = FMath::Lerp(
			CameraRelativeLocation.Z + DiffZPosition, // from this
			CameraRelativeLocation.Z, // to this
			Alpha
		);
	}

	return FVector(CameraRelativeLocation.X, CameraRelativeLocation.Y, CameraRelativeLocationZ);
}

*Method FTimeline execute on play or reverse

void USlideCrouchComponent::HandleCrouchHeight(const float Alpha) const
{
	if (IsValid(Character) && IsValid(Character->GetFPSCamera()) && Character->GetLocalRole() == ROLE_AutonomousProxy)
	{
		Character->GetFPSCamera()->SetRelativeLocation(GetRelativeCameraLocationOnCrouch(Alpha));
	}
}
  • When press crouch:
character->Crouch();
CrouchTimeline.Play();
  • When uncrouch
character->Uncrouch();
CrouchTimeline.Reverse();

How do you handle inconsistencies with line traces from camera between client and server (autonomous vs authority)?

Right now im not implemented line trace features… yet, so dont have a list of troubles, but yes, might give a desync between client and server line trace validation, maybe i will to add a threshhold on Z…

Some topics to beware about it ?

Depends on the type of game. For example I’m working on a BR. Line traces from camera are used for looting, and weapons firing. For projectiles I use the camera trace to determine down range trajectory… basically all of aiming.

Any discrepancies in the camera position, pitch, yaw between client and server results in a bad experience for the client. Server authority!

1 Like