I am currently struggling or better said having trouble with replication. I plan creating some kind of name places in my multiplayer game, so I decided to start with UMG:
Well the plan is now to set everyone the same name (“Horst)” on begin play (as a test case). When I hit “Tab” the character should be named “Manfred”.
Everyone named Horst as expected. But when I hit on “Tab” on one of the client machines, all others named “Manfred” but just for this machine. I expect that just the name for this character changes and replicates to all other client machines.
Maybe anyone could help me here.
Thank you guys for your time.
Hi, variable replication only works one way. From the server to the clients, there is no client to client communication. So if the server changes a replicated variable, then it will be updated for all relevant clients. If a client changes a replicated variable, it will only be changed locally for that client, nobody else will know about this.
If you want the client to tell the server something, you need to use a RunOnServer RPC (create a custom event, make it RunOnServer, second from the top here (search for ue4 run on server Replicating Functions in Blueprints) the direct link to that documentation page seems to be broken). The Server will then execute that event. So in your case
Also in your third image, you’re using GetPlayerCharacter with index 0 and access the Player Name from that. GetPlayerCharacter with index 0 will always return the local player character, so what you’re doing is that all your character names will display the one that the local player character has. So you would need a reference to the character the widget belongs to and use the name of that character instead.
thank you really much for the points you mentioned. I still have problems in what the approach is for passing a character reference. Should I bind the widget text to a function and access the character inside that or is it common to access the widget from character?
Btw here are the changed methods in character so far:
The widget binding function executes on tick, and since the character name only changes event driven, it would therefore be better to only change the name in the widget event driven.
To make it event driven, the first thing would be to make the PlayerName variable RepNotify. That way it will create a new function which will be called every time the PlayerName get replicated (so every time the PlayerName changes on the server and the server issues an update, the function associated with the repnotify will be called on all clients that received that update (and the server). Or in other words it will be called every time the PlayerName changes).
Now you need to get the change to the widget.
One way you could do that, would be to call an event inside the widget from the character inside the repnotify function and telling the widget the change/new name that way. → So character keeps track about all other objects that need to know about the change, other objects need to know nothing about the character
Another way would be via an event dispatcher. So inside the character you can create a new event dispatcher (call it something like OnPlayerNameChanged) and then call that event dispatcher inside the repnotify function. The second thing you need is for the widget to listen to that event dispatcher. So e. g. in EventBeginPlay of the widget, get a reference to the character and bind an event to the OnPlayerNameChanged event dispatcher. This event will then be called every time the player name changes. → So character knows nothing about all the other objects that need to know about the change, every object that wants to know about the change binds an event to the event dispatcher
Apparently AH has some problems again not posting the last comment, maybe this here will work… =)
In short:
Binding functions execute on tick, therefore it would be better to do it event driven. Make the PlayerName RepNotify and from the repnotify function either call an event on the widget telling it about the change or use an event dispatcher and bind the widget to that.
Hey and thank you really much for your help. I did some kind of the RepNotify part which is working now. Here is also the solution for other people around:
As you can see I created two functions called by the client. One for the name initialization part and one for updating the player’s name. In addition I added a variable to hold the player name which is set to “RepNotify”.
Switching over to the widget I added another variable to hold the player name. Afterwards I bound the character name to the variable using the function I mentioned.