[Networking] Interpolating replicated movement data in Pawn, without modifying source

Okay, so I’ve added my own tickbox to the defaults tab, known as bCustomLocationReplication, which forces the normal bReplicateMovement to be false (this replaces it). This is my way of controlling when the replication occurs - I can update the client’s physics simulation of its own controlled pawn via Super::Tick (as per the above screenshots of my BP_PlayerController blueprint), and store the result, and then manually trigger the replication, and interpolate between the new result and the stored (local) result. Is this an acceptable way to approach the problem?


void AShip::Tick(float DeltaSeconds)
{
	// Update AActor, including replication of movement.
	Super::Tick(DeltaSeconds);

	if (Role >= ROLE_Authority)
	{
		/* Some server-tracking stuff here [not relevant]. */
	}

	if (IsLocallyControlled())
	{
		FRigidBodyState RBState;

		FVector PreTickPos;
		FRotator PreTickRot;
		FVector PreTickVel;
		FVector PreTickAngVel;

		if (bReplicates && bCustomLocationReplication)
		{
			MeshComponent->GetRigidBodyState(RBState);

			PreTickPos = RBState.Position;
			PreTickRot = RBState.Quaternion.Rotator();
			PreTickVel = RBState.LinVel;
			PreTickAngVel = RBState.AngVel;

			GatherCurrentMovement();
		}

		FVector ReplicatedPos = ReplicatedMovement.Location;
		FRotator ReplicatedRot = ReplicatedMovement.Rotation;
		FVector ReplicatedVelocity = ReplicatedMovement.LinearVelocity;
		FVector ReplicatedAngVelocity = ReplicatedMovement.AngularVelocity;

		FVector LerpPos = FMath::VInterpConstantTo(PreTickPos, ReplicatedPos, DeltaSeconds, 0.001f);
		FRotator LerpRot = FMath::RInterpConstantTo(PreTickRot, ReplicatedRot, DeltaSeconds, 0.001f);
		FVector LerpVelocity = FMath::VInterpConstantTo(PreTickVel, ReplicatedVelocity, DeltaSeconds, 0.001f);
		FVector LerpAngVelocity = FMath::VInterpConstantTo(PreTickAngVel, ReplicatedAngVelocity, DeltaSeconds, 0.001f);

		SetActorLocation(LerpPos);
		SetActorRotation(LerpRot);
		MeshComponent->SetPhysicsLinearVelocity(LerpVelocity);
		MeshComponent->SetAllPhysicsAngularVelocity(LerpAngVelocity);
	}
	else // Should run on remote clients that don't own this Ship object?
	{
		if ((bReplicates && bCustomLocationReplication) || (bReplicates && bReplicateMovement))
		{
			GatherCurrentMovement();

			SetActorLocation(ReplicatedMovement.Location);
			SetActorRotation(ReplicatedMovement.Rotation);
			MeshComponent->SetPhysicsLinearVelocity(ReplicatedMovement.LinearVelocity);
			MeshComponent->SetPhysicsAngularVelocity(ReplicatedMovement.AngularVelocity);
		}
	}
}


The client control of the Ship is fantastic and smooth, even across the LAN. I’m worried that this isn’t actually a realistic representation, and the client is really just doing its own simulation, ignoring the server.

Additionally, clients do not receive updates about other clients, despite the last ‘else’ statement above, which should run on remote clients ticking the Ship (this is how it works, right? If the ‘Replicates’ tickbox is checked, all clients will run this tick function?

Some help would be appreciated!

Thanks :slight_smile: