Dynamic Skeletal Mesh Component added on server not replicated to later joining clients

Hi there,
I’m actually hitting a strange behaviour where i’m not sure it is a bug or just my lack of knowledge experience.

Context:
I’m implementing a multiplayer game with a dedicated or listen server. In case a player has joined the multiplayer game he is capable of changing his visual appearance, his avatar so to speak.

What is working:
If several client are connected to the server and one of those is changing its avatar this will be replicated to all clients and seems to work quite nice.

The Problem:
If a client joins late to the party he will see all player having their default avatar but not the ones they have already choosen. Only if the other player chooses its new avatar a second time after the player has joined this new player as well will see the new avatar of that player.

How it is implemented:
Each player is represented by it’s pawn. As soon as a new avatar was chosen the mesh associated with this pawn is changed - in detail a new skeletal mesh component is added while the old one is removed. This happens on the server. The pawn blueprint as well as all the assigned skeletal mesh components are set to be replicated.

My “confusion” or lack of knowledge:
At first I was - based on the documentation - convinced that it should be enough to add the new skeletal mesh component on the server side to get this created/replicated to all connected clients as well. This does not seem to be the case. Thus I configured the event on the pawn that adds the skeletal mesh to the pawn to be a multi-cast event. Which - effectively will add the new skeletal mesh on the server and all connected clients as the event runs on all those instances in parallel. This raises the question whether this is the desired and correct approach to this.

At second as the server knows the actual state of the pawn, including the new added skeletal mesh I’d assume if a new client joins the server the server will tell the client how the actual pawn is looking like wrt. to its actual instance and added skeletal components. But this does not seem to be the case if the client just spawns the pawn based on the default blueprint settings and not the actual runtime setup. Is this kind of expected behaviour? Would I need to mimic the adjustments to the pawn on each client after it has been spawned? If I do add the skeletal mesh components on the client side to be consistent with the server are they kept in sync btw. the client and the server from this time onward (wrt. animation and other properties) or how is replication setup in this scenario?

I’ve tried several approaches but none seem to be really satisfying thus searching for the swarm knowledge.

Any hint would be much appreciated to solve this.

Thanks in Advance.
André

Hi. You can store needed mesh as a replicated variable and set mesh component using it in construction script.

Thanks for this hint. I’d like to use this approach, however, the avatar mesh might consist of a hierarchy of skeletal mesh components which need to be added, thus a simple variable transferring this information from the server to the clients might not be enough.

So assuming I’m setting the variable with the contents to allow the client to reconstruct the skeletal mesh hierarchy, are the created components and their properties on each client replicated to each server/client (eg. their transforms) or would I need to implement this as well to notify the server once the owning client adjusts the components and than the server multicasts this to each client which then need to adjust it’s components accordingly?

Thanks in advance for any further input to help me to understand the mechanics here :slight_smile:

I didn’t get what you mean by:

I’ll make a guess you want to store image avatar with mesh. You can do that using structure.

As for how can you implement it.
I’ll make a guess you have skeletal meshes for players to choose from.
You can create Enum with names for meshes, so players can select from the list(your enum). You can use that with Select node in BP when setting skeletal mesh component.
Client → Server → Multicast.

If that works, no need for changes, just implement mesh selection into that.
For new players construction script will do.

Hi there,

thanks for your hints and details.
I’ve tried an approach to use an ActorComponent instead of a Struct. This allows me to implement further logic at BeginPlay to tweak the actual receiving actor with the proper avatar settings and mesh component assignments.

However, this seem to come with its own challenge :open_mouth:

The implementation assigns the specific ActorComponent on the server. The ActorComponents does have properties that are exposed on spawn. Therefore this parameters can be passed during AddComponentByClass.

If in this scenario a player joins late to the server everything is working as expected. The new joining client receives the actor from the server as well as the component that has been added with its parameters. Thus any additional BeginPlay activities are properly executed on the client …

BUT! If in this scenario a second player is already connected to the server and the first player chooses the avatar the custom ActorComponent gets replicated to the client BUT without the values it as been created using the AddComponentByClass blueprint function. So do you have any clue why this is the case?

Thanks in advance for any additional hint or idea.

Why do you need AddComponentByClass? Can’t you change existing mesh component?

Well, the Avatarsystems to choose from does have different skeletal mesh structure. One has a one component for the whole body, another one has seperated parts for head, torso, arms, legs and so forth. Therefore I’m using an ActorComponent that will construct the respective skeletal mesh components at the receiving avatar.

What’s confusing is, that the BeginPlay at the client seem to be called already after the initial creation of the component at server side without having the actual properties that has been used during instantiation with AddComponentByClass replicated as well.

This is kind of counterintuitive from my point of view.
Is there an event indicating replication for the ActorComponent is completed?

Can you show this?

Hi,

well I’ll try to record a video of the same. However, this was during my first attempt and I need to revert some stuff to get it back to this state.

The implementation at this stage was like the following:

  1. I created a ServerEvent on the Pawn as well as a MultiCast event.
  2. When the server event was called on the Pawn it just forwarded to the multicast event
  3. The multicast event added the required SkeletalMeshComponents to the Pawn.

So whenever one player/client selected an avatar the server event on the possessed pawn was executed and all seem to work fine.

However, if a player joins later on to the server he did not see any of the newly choosen avatars of any other player.

What you need to do:
Make replicated variable.
Copy your working code. Change it, so it will use replicated variable. And place it in begin play.
When a new player joins, it will fire begin play inside all characters on his side, and using replicated variable change characters too needed appearance.

Hi,

thanks for the hint.
Instead of adding the replicated variable directly to the Pawn I decided to use an ActorComponent that is added to the Pawn on avatar selection. The reason for this is, that each avatar system has todo some specific setup stuff on their BeginPlay
However, the ActorComponent does contain a replicated variable and the components BeginPlay does contain all the required setup, like you suggested. :nerd_face:

This approach is working quite fine now for all players joining late to the server. However, whet the ActorComponent is added to the Pawn using AddComponentByClass and passing initial properties that are exposed to be available at span on the server side while players are already in the game, the component as such gets replicated, BUT the BeginPlay is invoked before the replicated properties are available on the client. Thus, the player that has already joined the server can’t handle the change of the avatar :man_shrugging: .

I could try the OnRep_* approach to know on the client when a specific property has changed BUT the actual ActorComponent that is added to the Pawn requires at least 2 properties to be replicated to the client to properly initialise the avatar on that client. And there seem to be no guarentees in which order the OnRep_* notification gets called. So I’m kinda looking for a way to know at client side that the component is really properly initialised and all properties has been replicated after instantiation…

Any further hint would be much appreciated.

You can do it with Struct

Hey,
thanks.

The Struct and an corresponding OnRep_* did the trick and provided the missing piece so I got everything working.

I’ll mark the final post of yours as the solution even though the whole chain of tips lead to this final conclusion :nerd_face:

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.