Download

TextRender component replication not working

Good evening, fellow Devs,

in a multiplayer project, I’m using a TextRender component as name label above the character of each player.

Each time a new player connects to the server, he’s got to choose a name for his character.

Therefore, players are spawned as spectators and presented a simple widget containing a text input for the name as well as a confirmation button.

When the button is clicked, the widget calls a C++ function (ServerSpawnCharacter()) in the PlayerController base class.

The character is spawned delayed by utilizing ServerRestartPlayer().
A multicast is then used to set the name + character name label on each client.

ACPlayerController


UFUNCTION(BlueprintCallable, Server, WithValidation, Reliable, Category = "General")
void ServerSpawnCharacter(const FString& CharacterName);

UFUNCTION(NetMulticast, Reliable, Category = "General")
void MulticastInitialize(const FString& NewName);

void ACPlayerController::ServerSpawnCharacter_Implementation(const FString& CharacterName)
{
	ServerRestartPlayer();
	MulticastInitialize(CharacterName);
}

void ACPlayerController::MulticastInitialize_Implementation(const FString& NewName)
{
	((ACCharacter*)GetPawn())->SetName(NewName);
}

ACCharacter


FString CharacterName;

UFUNCTION(BlueprintNativeEvent)
void SetName(const FString& NewName);

void ACCharacter::SetName_Implementation(const FString& NewName)
{
	CharacterName = NewName;
}

The BP class inherting from ACCharacter (which is used as DefaultPawn class) overrides the SetName function in a way that also updates the name label text.

So basically: [Client]SpawnCharacter() -> [Server]SpawnCharacter() -> [Every Client]SetName() + Update Text Label.

The remaining issue is that players connecting afterwards don’t get the current value of already connected players name labels replicated, despite replication being enabled for the character BP and for the TextRender component.

To me it seems like the replication ain’t working correctly.

In fact, I only moved to using RPC for something as simple as this because simply setting the name label value on the server didn’t replicate back to the clients.

Any insight on this?

The TextRenderComponent does not replicate anything on its own (if you ignore parent classes) so even though you’ve enabled replication for it the text of the TextRenderComponent will never be able to replicate. Currently the name/text only replicates in your RPCs but as you’ve already noticed those may be missed due to relevancy. Players that weren’t connected at the time of the multicast RPC will also see the “timing issue” you’ve described (connecting players don’t get the current value of already connected players).

You’ll need to replicate the player name in a replicated variable instead so that both existing and connecting players will receive the updates the for name/text value. You’ll be happy to know that the replicated PlayerName variable is already taken care of in the PlayerState. The PlayerController also has a function called SetName which will send the desired name to the server (if it’s not an empty string). The server will then pass the name change through the GameMode which updates the replicated PlayerName variable of the PlayerState. So you may just be able to use some of this rather than re-inventing the wheel again.

If you want to read a little bit more from the documentation (networking content examples) I’d recommend this series:
2.1 - Network Relevancy [Part 1 - Not Replicated At All]
2.2 - Network Relevancy [Part 2 - Function Replication Solution Attempt] <- Your current approach
2.3 - Network Relevancy [Part 3 - Variable Replication Solution Attempt] <- available through APlayerState::PlayerName
2.4 - Network Relevancy [Part 4 - Combination Solution]

Well, my bad for completely overlooking the entire RepNotify mechanism.

I’ll probably have to make a distinction between player and character name, though.

Thanks for reminding me of a seemingly essential concept of UE4 networking.