Replicating SetActorLocation() smoothly while SetReplicatingMovement is true?

I’ve been trying to do some custom movement lately in the form of a quick dash. Right now I’m checking if a variable is true each frame, and if so, I’m using SetActorLocation(); to move the player forward X distance. The problem is that, while it replicates, the replication causes the client to move around jagged on client-side. On the server it moves fine.

When I use this while SetReplicatingMovement(false); the replication of the custom movement is perfectly fine. This tells me that there might be some kind of conflict between my movement and the base movement. Does anybody have any ideas on how to prevent this conflict? If any more information is needed, I’d be glad to provide it.

I’m also having the same issue with many other forms of movement like ApplyWorldOffset(); and even LaunchCharacter();! This can all be solved by just making my own movement for everything. Of course though, I’d rather not reinvent the wheel of movement if I don’t have to.

It may be down to how the movement is played back. A jump forward would potentially play back like a teleport. Also, the rate of replication could be a factor here, the default being once per second. you might need to adjust this value to 10 or 1/10th of a second. and it might improve the movement.

1 Like

Thanks for the answer @beegeedee! I’ll be investigating what you said to see if it helps. I’ve already looked into the replication as you suggested, and I wanted to ask if this has to do with MinNetUpdateFrequency? It’s what makes the most sense to me but I noticed that it’s default value is 2 rather than the 1 I would expect.

Yes, that’s the one. It represents 1/updatefrequency seconds so 2 is once every 1/2s and 10 is a good number.

1 Like

Unfortunately it doesn’t seem that setting it higher helped any. Turning MinNetUpdateFrequency to 10 doesn’t have any visual effect on the jitter, same with turning it up even higher. Could you give me a bit more info on the teleport idea you were talking about?

For reference, I’ll leave some of the essential code on how I’m going about doing this:

/* When the following is true...  (Checks each TICK) */

if (IsDashActive) { Dash(); }

/* Activate the following... */

void ABrawlTownCharacter::Dash()
{
	FVector NowLoc = GetActorLocation();

	const FRotator Rotation = GetControlRotation();
	const FRotator YawRotation(0, Rotation.Yaw, 0);
	FVector NowForward = FRotationMatrix(YawRotation).GetUnitAxis(EAxis::X);

	const float DisForward = 900.0f;

	FVector NewLoc = NowLoc + (DisForward * NowForward);

 // I added this to try and smooth the movement but it didn't work.
	NewLoc = FMath::Lerp(NowLoc, NewLoc, GetWorld()->GetDeltaSeconds());
			
	SetActorLocation(NewLoc, true);

	if (NowLoc.Equals(NewLoc))
	{
		GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Purple, FString::Printf(TEXT("Test F")));
	}

	Server_Dash(NowLoc, NewLoc);
}

void ABrawlTownCharacter::Server_Dash_Implementation(FVector NowLoc, FVector NewLoc)
{
	SetActorLocation(NowLoc, true);
}

You don’t want the MinNetUpdateFrequency to be higher than the maximum FPS you’re targeting, but 30 should be the max you need for a 60fps game and even 10 should do the job.

Since this doesn’t solve the issue, are you executing the dash in a single frame or is there messages being sent to the server for a series of steps? It’s more like a velocity change for a brief interval, say, speed burst of 5x normal max in a given direction for a period of 1/2 second or whatever you decide. This should then result in a series of server updates over n frames, depending on the client fps. e.g. 1/2 second boost would send increased velocity 30 times for a 60fps. The update MinNetUpdateFrequency of 10 should then show 5 updates over the 1/2 second period.

Remember, the movements should be done on the server and simulated on the client, then showing the truth on the replicated updates.

Have you tried asking about this on the discord too?

1 Like

Sorry for the slow response, I’ve been swamped with college homework. Thank you for all your help so far by the way!

Okay, so if that’s the case then I’ll set it to say 30 for now, and a lower value later when it’s working normal.

I am not executing the dash in a single frame, if you’re talking about the entire dash. I’m moving the actor forward a set amount of distance (for example, 50 units forward) each frame with SetActorLocation( ) each tick. I make sure to take DeltaTime into account as shown above. This repeats until the specified duration is over, like you said.

This is how I understand it:
So using a MinNetUpdateFrequency of 30, their position would be updated on the server 15 times in a second. If the client is running at 60 FPS, that would mean they would run the Dash( ) function 4 times (max) before the server receives the update for the first position. Maybe that’s the problem? Would the server take that position it received and then overwrite the client’s current position with it?

Also, I have tried asking about this on the Discord once but didn’t receive any responses. I will try to post it again and see if anyone else has some advice.

1 Like

The MinNetUpdateFrequency works by updating 1/MinNetUpdateFrequency second. For fps that is fps/MinNetUpdateFrequency so 30 would be once every 2 frames if you achieve 60fps but if you achieve 30fps, it would every 1 frame and so on.

It’s done this way so that players who cannot achieve 60fps get consistent update at the same time interval. 1/30 is really 1/30s or 30 times a second or approximately 0.03333s.

I hope this makes sense.

1 Like

This topic was automatically closed 20 days after the last reply. New replies are no longer allowed.

Privacy & Terms