Networking QuickStart tutorial shows DebugMessage for all players - correct behaviour?

I’ve just completed the Networking Quickstart tutorial, where the project is called ThirdPersonMP:…art/index.html

Part of the code is to show a debug message on the screen when health is lost (due to being hit by projectile), and as I understand it this text should only be visible for the player being shot at.

Also, this is explicitly mentioned in the guide:

However, when I run it locally, the text is shown on both screens. If I increase from 2 to 3 players the message is shown on all screens.

My understanding is that the way to differentiate players here is the [FONT=courier new]IsLocallyControlled() call:

void AThirdPersonMPCharacter::OnHealthUpdate()
    // Client-specific functionality
    if (IsLocallyControlled())
        FString healthMessage = FString::Printf(TEXT("You now have %f health remaining."), CurrentHealth);
        GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Blue, healthMessage);

        if (CurrentHealth <= 0)
            FString deathMessage = FString::Printf(TEXT("You have been killed."));
            GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Red, deathMessage);

    // Server-specific functionality
    if (Role == ROLE_Authority)
        FString healthMessage = FString::Printf(TEXT("%s now has %f health remaining."), *GetFName().ToString(), CurrentHealth);
        GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Blue, healthMessage);

    //Functions that occur on all machines.
        Any special functionality that should occur as a result of damage or death should be placed here.

Is this the expected behaviour, or does this mean that I have done a mistake somewhere along the tutorial? Or is it because when I run in in the editor all players are run locally “for me”?

My only deviation from the tutorial (AFAIK) is that I include [FONT=courier new]void HandleFire_Implementation(); in my ThirdPersonMPCharacter.h-file becuase otherwise it wouldn’t compile:


// in ThirdPersonMPCharacter.h

 /** Server function for spawning projectiles.*/
    UFUNCTION(Server, Reliable)
        void HandleFire();

    void HandleFire_Implementation();

I did some more fiddling with this, and I added the [FONT=courier new]Jump() command to the [FONT=courier new]OnHealthUpdate()-method. Then, the character being shot at (i.e. the character whose health is changed) is the *only *character that jumps.

This suggests that the replication works with regards to the[FONT=courier new] OnHealthUpdate()-method, and that the cause of my confusion is that the [FONT=courier new]GEngine->AddOnScreenDebugMessage(…)-method results in debug messages for all players.

Of course, if anyone have any other useful insights I’d be glad to hear them, *especially *if there’s a way to only show messages for certain players etc.

Thanks in advance, and have a great weekend.

I use the DrawDebugString method when I want to output stuff in multiplayer since you can output it in the game world attached to the actor. Anyway I just find the console too confusing in multiplayer so it may or may not help you. For example this outputs the actors Role above their head.

DrawDebugString(GetWorld(), FVector(0, 0, 100), GetRoleText(GetLocalRole()), this, FColor::Green, DeltaTime);

FString YourClass::GetRoleText(ENetRole Role)
    switch (Role)
        case ROLE_None:
            return "None";
        case ROLE_SimulatedProxy:
            return "SimulatedProxy";
        case ROLE_AutonomousProxy:
            return "AutonomousProxy";
        case ROLE_Authority:
            return "Authority";
            return "Error";

Thanks, that is much better!