Replicate static mesh actor position for late joining players

Ok. So I have a class that derives from AStaticMeshActor (replicated and replicated movement is set to true), the static mesh has enabled simulate physics. Everything works fine except, when a player joins a game that is already in progress, then the location of the static mesh is either correctly shown as on the server or as the initial position in editor. Once the static mesh position updates, it is replicated to all clients correctly once again. Any tips how to replicate the server position properly to late joining clients? I’ve tried calling OnRep_ReplicatedMovement(); on BeginPlay(), but it doesn’t help. It seems the initial transform of the object is properly updated only for clients that connect farther away from it.

You could try sending a request from the remote instance of the actor (on the late joiner) to the server for a position update in the remote BeginPlay - the server would then send back a vector (the position in world space) through a multicast RPC. In the RPC call, you could check if it’s a remote instance, and also have a boolean (not replicated) which checks if this particular instance of the actor sent an update request (so you only update the position on the late joining client). This will mean the client will need to wait a fraction of a second before it gets the update, but it should happen pretty quickly.

Thanks, unfortunately I cannot call a server function from remote instance of the actor since the late joiner is not the owner of the actor (thus the call to server function gets dropped). After some testing I have noticed that the location of the actor is updated properly, just the visuals of static mesh is sometimes stuck until that actor moves again, since I can line trace the object (client side line trace) on it’s actual position, where as line tracing the incorrect visual hits nothing.

On the screen it also seems that the objects moved a little bit (their initial position is either 0 and 90 degree) as we can see they are rotated a little bit.

You should be able to communicate with the server via the local player controller, and then have some RPC on the player controller which takes an actor (your static mesh actor) as an input, and then runs a function on the server instance of player controller which updates the static mesh actor’s position. This should work because every client can access their local PC, which is owned by the client and can communicate with the server. Only downside is you’re adding extra code to fix this issue, which might seem inelegant.

As for the location updating but the visuals not updating - can you clarify about this? If you print GetActorLocation on the client (and maybe GetWorldLocation for the static mesh component as well), does it not correspond to what you’re seeing?

After a while it turned out that moving code to constructor didn’t help and the objects still spawned with stale transform visuals for late joiners.The issue was in the editor setup. The correct component hierarchy for my custom actor class was:

→ MyActor

 -> **DefaultSceneRoot** (I was missing this)

     -> Cube (or other physical representation)

I’m leaving this in case someone else spends a few days trying to fix a code issue that is likely not a code issue at all.

---- PREVIOUS MESSAGE ----

If you have a custom AActor subclass make sure to enable replication in the constructor and not in the BeginPlay event.

 AYourActor::AYourActor()
    {
    	if (HasAuthority())
    	{
     		SetReplicates(true);
    	}
    }

For some reason even hough BeginPlay gets called for the late joiners it seems the state doesn’t get replicated until first change.