Hello,
I’ve been trying to understand how object and event replication works between server and clients and, after running some successful tests that lead me to believe I understood, I’m now confused more than ever when the following blueprint gave me undesired results.
The goal is to have all clients update the name plates for all characters with their respective names when a new player joins the session. Currently, this is causing previously joined players’ name plates to update to any newly joined player’s name. Can anyone point out what I’m not understanding correctly?
It might be that the problem is not in this loop, but in the code that sets or replicates the name.
Typically, the name of a player lives in the PlayerState, and you’d loop over all playerstates to find the players.
Separately, if you have some relationship where you want “display of thing X” to change when “thing X” changes, the typical use is to mark the property as RepNotify and use the OnRep notification to update the display. If the name is already a property on a character, all you need to do is implement this inside the character, and each character will sync itself, no need to loop.
The result is that all clients properly update the name plates of new players joining but any new players joining do not get name plates of existing players.
I need to find a way to tell new players joining the session to update name plates of those who have already joined.
Why would the old players not get the right name plates?
Assuming the property is properly replicated, and there is appropriate data binding from the property to the name plate, it should Just Work ™ when you change the property on the server.
In fact, if you read the property value from the player to the GUI using property binding, you don’t even need RepNotify, just regular replication. Just update the property value on the server, and it replicates out to each client, and they all draw the right value.
That’s what I figured but the results I’m getting when I test don’t follow and it’s really confusing me. Here’s another try using gamestate’s player array. It triggers after playercontrollers possess their character pawn :
With that, I get the following result: first client/server gets all new player nameplates right but any new clients joining get default value in all player name plates. I set the widget component and any parents to replicate too. There must be something more basic that I’m missing…
If you are iterating over the values, then clearly you’re not following the simplest method of “just rely on replication and read the value in the GUI.”
The loop you have with UpdatePlayerNameplatesOnServer() will of course only run on the server, and GUIs don’t replicate. (In fact, many servers don’t even have a GUI, if they are started in dedicated mode.)
Your second list with SetNewNameOnServer() and SetCharacter(), also only runs on the server, and still doesn’t seem to do anything with the OnRep callback (unless that’s in some other code you’re not showing.)
It looks to me as if you’re just fundamentally confused about how replication works.
It makes things simpler than what you’re trying to do.
Do this:
Update your name card widget to have a property that’s the type of your pawn, call it TheCharacter.
Click the “text” bit of your name card widget, and choose Bind … and in the event it generates, extract and return the name from the character object.
If you use the player state, that’s all you need.
If you put the name in the character object, you will also need to make sure that the name property on that object has “replicates” turned on.
That’s it! When you change the name in the character, the GUIs on all the clients should display the new name.
For more information, start reading about “Variable Replication” in the documentation:
It works! I set up the name plate to now keep a reference to the character pawn with the replicated name and I bound this value to the text component.
I had a feeling replication was much simpler than what I was making it out to be with my attempts and your example brought me back to basics and made me understand.