Changing Material in Multiplayer

Hi,

On a map a player chooses a skin. Then, name of that skin is saved as a string in players GameInstance. Later when one player hosts and other one joins, their desired skins should be apllied to their meshes.

Now here how I tried it to do:

In construct I get the GameInstance and then say to the server to change my skin, so everyone changes his skins to desired ones.

Then the server multicasts to everyone to change their skins.
Everyone finds their skin in a map and sets the material of mesh.

The problem you can see here:

On the left we have a server that has its desired skin, but it also apllied its skin to the client.
On the right we have the client that also has its skin, but it did the same thing as server.

image

I want that server sees on his character his skin, and client to see his skin and skin from server.
I dont understand why is it doing it and how to solve it.

Please help!

when the client loads, his info must go to the server then the server loads his clothing info on him and not other players. This must happen for each client. The server will replicate that info to all clients. So they see the right clothing on that client.
Hope this makes sense.

1 Like

The problem is you’re doing game logic in the construction script. The construction script does not run in the game, only the editor. Move what you have in the construction script to the BeginPlay event in the event graph.
Edit: The “SR_ChangeSkin” is being called from the construction script, so it is working. But I read somewhere that the construction script doesn’t run in game builds. You can test to see if that’s correct or not.

There’s a second problem:
In the “MC_ChangeMySkin” event, you are accessing the skin from the game instance. The game instance is not replicated; it is local to each player (only exists on the player’s machine). This explains why all characters use the player’s selected skin. What you need to do is send that through the event. So in the “SR_ChangeSkin” event, add an input called “Skin” and send it through that; that will send the skin to the server. Then, in the “MC_ChangeMySkin”, do the same thing; this will send the skin to each client.

1 Like

it almost works. But not fully.

This is server:
image

these are two clients:

Well, I think I understand why, client connects but doesnt know that they have skins, they have to update their skins.

I dont understand how I can update them. I tried to make an Event OnPostLogin in GameMode, it would send to all player characters a message to update their materials but I cant get on their variables = I cant get into their GameInstance where the skin is. I also tried to save the skin string in a variable, cant access either. Its all executed on server, I get the server variables.

So I simplified your setup a lot by using an RepNotify variable. The client sends the skin to the server and the server sets the skin variable. Because the skin variable is replicated, it replicates it to all clients. Because the variable is RepNotify, when it changes. it runs a function that sets the skin on the character.

Event graph:


OnRepSkin (automatically generated):
image
Result:

The benefit of doing it this way is that it uses a variable instead of a multicast event, so players who join later will have the most up-to-date value without needing to be sent it through an event.


Also, if your skins are user-generated content, they will only exist on the user’s computer, so you will need to send & store them on the server so that every player can see them.

4 Likes

Very Thank you, Helped alot. It works now. Huge respect!
I have a question: when the OnRepSkin notify fires, which mesh does it take? The mesh from character that send to the server request?

1 Like

Yes. The mesh is from the character that it is inside (if you get what I mean); the character that changes the skin.

2 Likes

This is the way to go. If you are working with (Dynamic) Material Instances, you do not need to replicate the materials themselves but could also extract the parameters and replicate them to the clients.