Attached character lags on the client machine

I currently have a problem that when I attach a Character to a Vehicle, and the vehicle moves fast, the client controlling the character sees it lagging/falling behind, there are even situation when the character leaves the bounds of the vehicle completely.
Although, on the server, all looks fine, client character is attached correctly and does not lag.

Any idea how to fix this?

I guess it’s due to the fact that the client does not simulate the moving vehicle, so the server has a moving pawn and replicates the location to all clients, but for the client it’s not moving and it’s own simulation just overrides the location that gets sent from the server.

So to fix this, I would replicate all necessary data that the clients simulation can stay in synch witht the server.

Both vehicle and character are set to Replicate (including movement).
The problem is shown in the following video, where what you see is the client view, the other guy is local to the server.

Note that in the server’s viewport the problem does not exists, I see both characters attached to the vehicle just fine.
Any idea what is wrong?

I still think that the client side prediction does not handle the vehicle movement and therefore lags behind the server version itself.

Make sure you replicate the necessary things like the character state (wether or not he is in a vehicle) and all necessary stuff for the vehicle as well (like engine rpm and such). And then let the client run a non authoritative movement prediction.
You wan’t the client to simualte all the movement the server handles. So when the location values from the server get replicated, the clients approximate location should be already pretty close to that.
If you don’t simulate the movement on the client, stuff will always be a bit out of synch, until the server sends in the new information.

Look at MovementComponent::SimulateMovement for reference.

Thanks for taking the time to reply.

I though this was already the case.
The character being in the vehicle is already replicated, and server has authority over both vehicle and characters.

I attach the character to the vehicle (character’s capsule component > vehicle’s mesh) in both server and client, and character movement mode is set to MOVE_None.
From the client, I see the vehicle’s location correctly, just the character itself is lagging behind. Which leads me to think that the vehicle’s location is correctly replicated to client, the client’s location on the other hand, lags behind (when attached to the vehicle).

Hard-attaching the character to the vehicle might fix that. It doesn’t seem to be an issue related to movement prediction, since the vehicle is still in the correct place. You will get minute amounts of jitter, but you can Interpolate between the positions you receive from the server for a more smooth experience using PostReceiveNetVelocity().

It might be being caused by BaseMovement in the character, try switching ‘ImpartBaseVelocity’ off (or whatever the setting is) when inside a vehicle and see if that helps it a little.


GetHumanMovementComponent()->bImpartBaseAngularVelocity = false;
GetHumanMovementComponent()->bImpartBaseVelocityX = false;
GetHumanMovementComponent()->bImpartBaseVelocityY = false;
GetHumanMovementComponent()->bImpartBaseVelocityZ = false;

Doesn’t seem to help. :frowning:

Interesting… In my experiences with Vehicles I’ve been deleting the characters when they enter it (since you’ll never see them), but if you need to visualize the character that might not be the best approach.

The only other thing I can suggest is simulating the vehicle movement on both Client and Server, though that might mean doing your own vehicle code. It looks like it’s caused by the client not knowing where its supposed to be, so as it gets updates from the server (which will be behind the real game time by a fraction or so, depending on latency), they’ll just ‘snap’ to that point.

Ok, so I was able to find the source of the problem, and is within CharacterMovementComponent, by disabling the component tick, the issue seems gone.
Although, other issues arise such as the character UCharacterMovementComponent::TickCharacterPose(float DeltaTime) does not get called. Possibly other issues too.

So the cause is definitely UCharacterMovementComponent::SmoothClientPosition(float DeltaSeconds).
Problem is, there is no way to disable this (without modifying source). A simple flag would do the trick.

EDIT: Disregard, UCharacterMovementComponent::SmoothClientPosition(float DeltaSeconds) is virtual, so all is good.
Thanks a lot for the help. :wink:

You are totally right, I was able to solve it in the following way:

// Delegate
OnCharacterMovementUpdated.AddDynamic(this, &AHuman::OnMovementUpdated);

void AHuman::OnMovementUpdated(float DeltaTime, FVector InitialLocation, FVector InitialVelocity)
	if (IsInAVehicle())
		FVehicleCompartment CompartmentSetup = Vehicle->GetCompartmentsSetup()[VehicleCompartmentIndex];

And this solved the problem in a clean and easy way. :wink:

Hey, So what exactly was your fix, and can this be done in blueprints, I tried following through (I am having this exact problem aswell)but it still lags on mine, my discord is CapnC4ke#9414, if you are up to trying to help me fix mine. Thanks in advance!!