I have found there are a few ways you can tackle the issue of equipment/weapons and replication. First there are a few assumptions I am going to make as to your setup. The first assumption is you are attempting to attach a weapon to a socket defined by the character skeleton. You mentioned that Parent is set by using SetOwner function, I then assume this may be happening in a component? Either way if the value of Parent is a “Character” or “Pawn” object, you still need to call Parent->GetMesh() because if you have defined your socket from your skeleton then the socket is on the skeleton not the Pawn or Character.
Now if you are attaching the actual Skeletal/Static Mesh Component (which it sounds like you are), then (in theory) if the “Owner” of the Skeletal/Static mesh component IS the Pawn/Character its properties should replicate down to the clients. However if this is not the case (say the owner is a separate Weapon Actor a.k.a. “Weapon Item”) then you need a property on the Pawn/Character that replicates to the clients the Skeletal/Static mesh component set to it. This is one method you can use.
I personally use another method that may work for you. Now I use Skeletal Mesh but you can use Static Mesh all the same. Create a SkeletalMeshComponent for your Pawn, construct it in the constructor. Then Create Multicast functions that are used to set a Skeletal/static mesh to the component on all clients. These functions are called by your equipment system chain, and only change the aesthetic appearance of your character.
MyCharacter.h
class AMyCharacter : public ACharacter
{
// Your standard UE4 code stuff.
UPROPERTY(EditDefaultsOnly)
FName * weaponSocketName;
// you do not need to replicate this to the client, the multicast function is responsible for changing the
// mesh on all clients.
UPROPERTY()
SkeletalMeshComponent * weapon;
UFUNCTION(BlueprintCallable, Category="Equipment")
SetWeapon(skeletalMesh * skeletalMesh)
UFUNCTION(BlueprintCallable, NetMulticast, reliable)
MulticastSetWeaponMesh(USkeletalMesh * newMesh);
MulticastSetWeaponMesh_Implementation(USkeletalMesh * newMesh);
}
MyCharacter.cpp
AMyCharacter::AMyCharacter(const FObjectInitializer & objectInitializer)
{
this->weapon = objectInitializer.CreateDefaultSubobject<USkeletalMesh>(this, weapon);
this->weapon->AttachTo(this->GetMesh(), this->weaponSocketName);
}
void AMyCharacter::SetWeapon(SkeletalMesh * newMesh)
{
// only do this if we are the authority/server.
if(this->Role == ROLE_Authority)
{
this->MulticastSetWeaponMesh(newMesh);
}
}
void AMyCharacter::MulticastSetWeaponMesh(newMesh)
{
// you can do some checking for null here if you like, but since "unequip" is an option that uses bare
// handed attacks null is acceptable.
this->weapon->SetSkeletalMesh(newMesh);
}
For this setup there are a few things to note. Multicast functions should be protected as they set the mesh on EVERY client. While the stats of your weapon would not change if you are doing melee weapons with collision tests with the actual model’s collision boxes (instead of a general line trace, sphere or a static collision component for hit detection). Basically you don’ t want someone to exploit these easily, so make them protected.
The reason I used this setup is because native replicating a Static and Skeletal mesh component proved problematic especially when utilizing animations and animation trees. For weapons this is not always a problem but for equipment such as swap-able armor that needs to synchronize with a master skeletal mesh it was.
Again this is all depending on how you keep your objects, inventory, whatever. I believe you could also directly attach an actor to a socket so that may be another option.