Setting the mesh to null on the server works, but when the value is replicated to clients it gets ignored. The problem is that OnRep_StaticMesh() sets StaticMesh to NULL before it calls SetStaticMesh(NewStaticMesh). Inside SetStaticMesh there’s an early return for if StaticMesh == NewStaticMesh. Since StaticMesh is NULL and we’re trying to set to NULL it jumps out, never actually updating anything.
void UStaticMeshComponent::OnRep_StaticMesh(class UStaticMesh *OldStaticMesh)
{
// Only do stuff if this actually changed from the last local value
if (OldStaticMesh!= StaticMesh)
{
// We have to force a call to SetStaticMesh with a new StaticMesh
UStaticMesh *NewStaticMesh = StaticMesh;
StaticMesh = NULL; // <---Should be OldStaticMesh instead to properly compare
SetStaticMesh(NewStaticMesh);
}
}
I tested replication of a static mesh in a project by setting a blueprint to change its static mesh during play. With the BP actor set to replicate I saw the mesh change only on the server/client that called for the change. This is likely caused by the same thing that you pointed out on the code side and the lack of functionality (both code and blueprint) have been bugged (UE-16478).
This issue is still present in 4.18.3 as I just ran into it this week. Specifically the code I am using is
GetMesh()->SetSkeletalMesh(DefaultMesh);
Which does not appear to replicate. Including a separate SkeletalMesh component on the PlayerCharacter and using that instead resolves this issue.
I would be fine with just the documentation including details about this as to reduce the amount of stumbling around to figure out why something isn’t working.