Replicated Sprinting system - Problem with animation


I am currently working on a sprinting system for UE4, which is written in C++, and I have a problem with one of the animations.

The sprinting system works perfectly with the increase of the speed, the code goes as following (This is a thirdperson UE4 project).


UFUNCTION(Reliable, Server, withValidation)
void StartSprint();
UFUNCTION(Reliable, Server, withValidation)
void EndSprint();


bool AMyGameCharacter::StartSprint_Validate()
	return true;

void AMyGameCharacter::StartSprint_Implementation()
	CharacterMovement->MaxWalkSpeed = 600.0f;

bool AMyGameCharacter::EndSprint_Validate()
	return true;

void AMyGameCharacter::EndSprint_Implementation()
	CharacterMovement->MaxWalkSpeed = 400.0f;

Now, this is the part where the problem occurs. I use a Blendspace 1D to handle my three animations: Idle, Walk and Sprint.

If I test with 2 clients, both of the clients can see: The idle animation and the walk animation. For some reason, when I hold down my key to sprint, the client which should have been sprinting, sees the walking animation as “lagging” (it is not switching over to the sprinting animation), while the second client sees the sprinting animation perfectly.

I also did a test with three clients at once, with the following result:
Client 1 was sprinting.
Client 2 and 3 was observing.

Client 1 could only see the walking animation as lagging, while client 2 and 3 was capable of observing the sprinting animation.

I do not believe that it is a problem with the float for speed, otherwise it would not register that the client should switch between idling and walking. I would be very grateful to have some help on this issue. :slight_smile:

Can you show the function where you actually call StartSprint and EndSprint?

What I suspect the problem is that the value only changes on the server and I don’t think MaxWalkSpeed is replicated, so only the server knows about the change. You need to make sure that both know it. So if you’re calling it on the client, call the server command and then immediately change it locally too.

Does that make sense? Seeing the code where you’re calling StartSprint will help out answering this question.

Yes, I think that gives sense. My StartSprint and EndSprint is called by holding the shift key, which is handled in an InputComponent.

InputComponent->BindAction("Sprint", IE_Pressed, this, &AMyGameCharacter::StartSprint);
InputComponent->BindAction("Sprint", IE_Released, this, &AMyGameCharacter::EndSprint);

Where I have added to DefaultInput.ini:


I just checked CharacterMovementComponent.h

/** The maximum ground speed. Also determines maximum lateral speed when falling. */
UPROPERTY(Category="Character Movement", EditAnywhere, BlueprintReadWrite)
float MaxWalkSpeed;

MaxWalkSpeed is not replicated.

So changing this on the server would result in a higher walking velocity on the server and a higher replicated velocity to all clients. But the client simulation could still override the velocity with their own MaxWalkSpeed values, which could cause problems with your animations.

So I would suggest to just add a bool

UPROPERTY(Transient, Replicated)
uint8 bWantsToRun : 1;

set it to true in ServerStartSprint_Implementation() and let it replicate to all clients.

Then override the CharacterMovementComponent’s GetMaxSpeed() function and incorporate the running speed in there. That is essentially what ShooterGame does :smiley:

Thank you. :slight_smile: I took a derival of how running is handled in the Shooter Game, and added it to my character’s animation blueprint. I could post the solution, but it would take a lot of space in a post. It simply requires to take a look into the “State machine” of the character in the Shooter Game.