Character Movement Replication, Sprint

Alright, so i thought i understood RPC functions. But I guess not. I need help. So in the thirdperson template I wanted to test out a sprinting function. I binded in my project editor and everything a sprint then made a start/stop sprint function with a bool bSprint to check. So theres that. Mind you, I replicated my bSprint variable. So then i made a serversprint with the proper uproperties. Then i made a regular sprint that just handled regular sprinting logic so i can call it in the serversprint_implementation. Heres what it looks like.


void AMMOCharacter::StartSprint()
{
if (Role < ROLE_Authority)
{
bSprint = true;
ServerSprint();
}
}
void AMMOCharacter::StopSprint()
{
if (Role < ROLE_Authority)
{
bSprint = false;
ServerSprint();
}
}

void AMMOCharacter::Sprint()
{


if ((Role >= ROLE_AutonomousProxy) && (bSprint))
{
GetCharacterMovement()->MaxWalkSpeed = 7000.0f;
}

}

bool AMMOCharacter::ServerSprint_Validate()
{
return true;
}

void AMMOCharacter::ServerSprint_Implementation()
{
Sprint();
}

So then i tried with a “ClientSprint” because maybe it was client calls, server checks, then goes back to client. Still didnt work. Also tried with netmulticast, still nothing. Please, what am I misunderstanding here?

For proper sprinting (to work with the Character Movement Component) you really want to handle it via the Character Movement Component. Issue is, when you sprint, you are adjusting the “Walk Speed”. This can lead to situations where the server doesnt quite get updated in time, the client sends in its location different to what the server thinks it should be, and ends up being corrected. This will cause “rubber banding”. More noticable on higher pings (>150). But for your crude implementation, you are kinda doing it weird.

in your header file, you want:



UPROPERTY(BlueprintReadOnly, ReplicatedUsing = OnRep_IsSprinting)
bool bIsSprinting;

UPROPERTY(EditDefaultsOnly)
float SprintSpeed = 800.f;

UPROPERTY(EditDefaultsOnly)
float WalkSpeed = 600.f;

void SetSprinting(bool bNewSprinting);

UFUNCTION(Server, Reliable)
void ServerSetSprinting(bool bNewSprinting);

UFUNCTION()
void OnRep_IsSprinting();



then in your cpp file:



 bool AMMOCharacter::ServerSetSprinting_Validate()
{  
return true;
}  

void AMMOCharacter::ServerSetSprinting_Implementation()
{  
SetSprinting();
}  

void AMMOCharacter::OnRep_IsSprinting()
{
     GetCharacterMovement()->MaxWalkSpeed = bIsSprinting ? SprintSpeed : WalkSpeed;
}

void AMMOCharacter::SetSprinting(bool bNewSprinting)
{  
    if (Role < ROLE_Authority)  
    {    
        ServerSetSprinting(bNewSprinting);  
     }

    bIsSprinting = bNewSprinting;  
    GetCharacterMovement()->MaxWalkSpeed = bIsSprinting ? SprintSpeed : WalkSpeed;
}

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

   DOREPLIFETIME_CONDITION(AMMOCharacter, bIsSprinting, COND_SimulatedOnly);
}
 

@TheKaosSpectrum thank you! I will try this out now. So did i pretty much have the concept right but execute it wrong? Also, what is this line here?


GetCharacterMovement()->MaxWalkSpeed = bIsSprinting ? SprintSpeed : WalkSpeed;

is that a flag?

EDIT: Also what function would i bind my button to? Second


 
  bool AMMOCharacter::ServerSetSprinting_Validate() {   return true; }    void AMMOCharacter::ServerSetSprinting_Implementation() {   SetSprinting(); }    

isnt consistent with the header so i added bNewSprinting to all functions. Not sure if this was intended but it isnt working :confused:

GetCharacterMovement()->MaxWalkSpeed = bIsSprinting ? SprintSpeed : WalkSpeed;

This is a ternary operator, meaning if bIsSprinting is true, then it will use SprintSpeed else it will use WalkSpeed.

Not sure what is not working, any chance to provide some more details?

Also this won’t work if ran on server, if you want it to be activated on the server, change the rep condition to COND_None.

@TheKaosSpectrum So I tried using this and it seems that when i press shift nothing happens. Im using the playerinputcomponent to bind my left shift to sprint. I tried creating a startsprint stopsprint, because you cant bind functions that have parameters. But ill be playing around with it maybe i can get the concept down and get it working. I think im pretty much headed in the right direction but if you get back to me before then, even better :slight_smile:

Anyone out there? Am i really just not understanding RPCs?

I haven’t gotten back to doing this on my project yet. Too many other unknowns I been working on. I seem to remember Tom’s project he shared, https://www.tomlooman.com/survival-sample-game-for-ue4/ , has sprint working. Maybe that will help you.

Hi, its too late, but i have my own variant how to replicated sprint.
h:
image
cpp:
image
Im not sure about this variant, I’m just starting to learn multiplayer programming

Movement component has been initialized previously, SUSpeed and MWSpeed - too

hi, u must use bool bIsSprinting variable