I’ve been pulling my hair on this one. I have a multiplayer game and i cannot get the players to sync/set players name above their head in a good ol’ text component.
The flow is as following: onPostLogin and then setName on playerState from a cast.
what now? I’ve tried to use eventBeginPlay on the playerState, since it seem to run everytime someone joins. but I cannot get the names to update on every character.
What’s the best practice flow for these kind of operations, where every player needs to know something about the other players, even if they join later on in the game?
When a Client connect to a Server it can pass information to the server so the server will have the value already available during the Login call.
This is done when the Client calls “OpenLevel” in the “options” parameter.
Nameis a key that GameModeBase is already looking for when logging in a new player.
The client when calling OpenLevel could then add
Name=MyName to the “options” field.
The PlayerState Class already replicate “PlayerName” and have a function in c++ for OnRep_PlayerName. If you want a callback in Blueprint you could declare a multicast Delegate and call it when OnRep_PlayerName is called.
The Pawn class also has a OnRep_PlayerState function that you should also also declare a multicast Delegate for.
Now the final steps is to bind an event to the OnRep_PlayerState Delegate on the Pawn class followed by binding an event to the OnRep_PlayerName Delegate on the replicated PlayerState. Whenever this PlayerName Delegate is called is when you update the Widget name field.
- Add the option
Name=MyName to the OpenLevel call on the client
- Add and call a Delegate for OnRep_PlayerState in C++ on the Pawn/Character class.
- Add and call a Delegate for OnRep_PlayerName in C++ on the PlayerState class.
- Bind an Event to the PlayerState Delegate
- Bind an Event to the PlayerName Delegate by the Event in step 4.
- Use the step 5 Event to update the widget name field.
If you want to avoid c++ you would need to make a duplicate of the PlayerState variable on the Pawn/Character and make it a RepNotify variable and set it by the Server when “OnPossessed” is called.
You also need to duplicate PlayerName on the PlayerState and make it RepNotify and set it by the Server when “OnChangeName” is called on “GameModeBase”.
To be able to bind to the callbacks for both variables also create an Event Dispatcher for both OnRep_PlayerState and OnRep_PlayerName.
Wow, thanks for the detailed and very informative answer. I’m currently working on blueprints so that’s the path I’m going to take. I manage to solve it with RepNotify on playerName in the character and playerState. I figure I can do this with a whole structure, tho, I’m not sure if I should store information about the players current money, location and other things that should be saved when leaving the game and/or joining. I’ve read that stuff like that should not be stored on the playerState, but I did not really get an answer for where It should be stored.
I’m still a but rookie on ‘what goes where’ in this multiplayer jungle.
Thanks for the answer, worked like a charm. <3
edit: Is it possible to fake the name-flag when testing in the editor? I’m testing two client only since I’m using a dedicated server.
PlayerState is for indivual player info that other players want to know about.
GameState is for game wide info not bound to a specific player that all players needs to know about.
GameMode is for server only logic that noone except the server needs to know about.
PlayerController is an isolated connected between the server and the client that none other than the specific client and the Server knows about.
I think I’m doing the same that you have said in the answer, but in step 5 it updates both widgets: Change on one PlayerState->PlayerName updates all Players with the same name
Do you have an idea about what it is happening?
For posterity, an answer can be also found in this thread.