Replication of Collision Response changes. Am I missing something?

Working on a multiplayer platformer wherein the players will be able to jump up through some platforms. The idea I had was that certain actions (jumping, double tapping downwards, etc) would put a pawn into ‘passthrough’ mode, that is, change the collision response of that pawn to a certain channel, on which those platforms exist, from block to overlap.

With the code I have, it works great locally. However, when testing it out networked (via the multi-client feature in the editor), the movement of remote players is erratic when jumping through platforms, as their mesh flits around the item they’re jumping through.

Is there a piece I’m missing?

SidescrollerCharacter.h

class ASidescrollerCharacter : public ACharacter
{
...

UPROPERTY(Replicated)
	bool bShouldGoPassthrough;

	UPROPERTY(Replicated)
	int32 bNumOverlaps;

protected:
...
	virtual void Jump();
	
	virtual void Tick(float DeltaSeconds);

	UFUNCTION()
	virtual void OnOverlapBegin(AActor* OtherActor);

	UFUNCTION()
	virtual void OnOverlapEnd(AActor* OtherActor);

	void SetPassthrough(bool bState);

	UFUNCTION(reliable, server, WithValidation)
	void ServerSetPassthrough(bool bState);

SidescrollerCharacter.cpp

... Inside the constructor
	bShouldGoPassthrough = false;

	CapsuleComponent->bGenerateOverlapEvents = true;
	CapsuleComponent->bMultiBodyOverlap = true;
	this->GetRootPrimitiveComponent()->bGenerateOverlapEvents = true;
	this->GetRootPrimitiveComponent()->bMultiBodyOverlap = true;
	OnActorBeginOverlap.AddDynamic(this, &ASidescrollerCharacter::OnOverlapBegin);
	OnActorEndOverlap.AddDynamic(this, &ASidescrollerCharacter::OnOverlapEnd);

...
void ASidescrollerCharacter::Jump(){
	ACharacter::Jump();
	SetPassthrough(true);
}

void ASidescrollerCharacter::Tick(float DeltaSeconds){
	ACharacter::Tick(DeltaSeconds);

if (this->GetVelocity().Z <= 0 && bShouldGoPassthrough){
	if (bNumOverlaps == 0){
		this->SetPassthrough(false);
	}
}
}

void ASidescrollerCharacter::SetPassthrough(bool bState){
	if (bState){
		bShouldGoPassthrough = true;
		this->GetRootPrimitiveComponent()->SetCollisionResponseToChannel(ECC_WorldStatic, ECR_Overlap);
		this->GetRootPrimitiveComponent()->SetCollisionResponseToChannel(ECC_WorldDynamic, ECR_Overlap);
	}
	else{
		bShouldGoPassthrough = false;
		this->GetRootPrimitiveComponent()->SetCollisionResponseToChannel(ECC_WorldStatic, ECR_Block);
		this->GetRootPrimitiveComponent()->SetCollisionResponseToChannel(ECC_WorldDynamic, ECR_Block);
	}

	if (Role < ROLE_Authority){
		ServerSetPassthrough(bState);
	}
}

bool ASidescrollerCharacter::ServerSetPassthrough_Validate(bool bState)
{
	return true;
}

void ASidescrollerCharacter::ServerSetPassthrough_Implementation(bool bState){
	SetPassthrough(bState);
	print(TEXT("WOO"));
}

void ASidescrollerCharacter::OnOverlapBegin(AActor* OtherActor){
	++bNumOverlaps;
	print(TEXT("Begin Overlap"));
}

void ASidescrollerCharacter::OnOverlapEnd(AActor* OtherActor){
	--bNumOverlaps;
	print(TEXT("End Overlap"));
}


void ASidescrollerCharacter::GetLifetimeReplicatedProps(TArray< FLifetimeProperty > & OutLifetimeProps) const
{
	Super::GetLifetimeReplicatedProps(OutLifetimeProps);

	//Replicate to all
	DOREPLIFETIME(ASidescrollerCharacter, bShouldGoPassthrough);
	DOREPLIFETIME(ASidescrollerCharacter, bNumOverlaps);
}