Actor on server are invisible on clients

I am trying to spawn weapons on server and attaching it to the clients but I am not able to do so.

The weapons don’t appear visible to the clients.

Here is my code.

Character.cpp

    void APSETPCCharacter::BeginPlay()
    {
    	if (Role == ROLE_Authority)
    	{
    		SpawnDefaultWeapon();
    	}
    }
    
    void APSETPCCharacter::SpawnDefaultWeapon()
    {
    	if (Role < ROLE_Authority)
    	{
    		return;
    	}
    
    	if (DefaultWeapon)
    	{
    		UWorld* World = GetWorld();
    		if (World)
    		{ 
    			ABaseWeapon* TempWeapon = GetWorld()->SpawnActor<ABaseWeapon>(DefaultWeapon);
    			TempWeapon->SetOwner(this);
    			TempWeapon->OnEquip();
    			CurrentWeapon = TempWeapon;
    		}
    	}
    }

And the weapon attachment is called from OnEquip() function like this.

    void ABaseWeapon::OnEquip()
    {
    	/** Do weapon equip things bla */
    	OnWeaponSpawn();
    }
    
    void ABaseWeapon::OnWeaponSpawn()
    {
    	GEngine->AddOnScreenDebugMessage(-1, 5.0f, FColor::Red, "QWeqwe");
    	ItemMesh->AttachTo(OwningPawn->GetMesh(), FName(TEXT("WeaponSocket_Rifle")));
    }

Some addition constructor changes I made to the weapon are

{
	ItemMesh = ObjectInitializer.CreateDefaultSubobject<UStaticMeshComponent>(this, TEXT("Weapon"));
	RootComponent = ItemMesh;
	
	PrimaryActorTick.bCanEverTick = true;
	bReplicates = true;
	bNetUseOwnerRelevancy = true;
}

The weapons appears to have been by a ghost on the client side. The weapon moves even if the client doesn’t move.

link text

Shows more exactly what is happening.

We had this exact same problem in The Dead Linger, and in TheVOID.

What happens is that on the server the weapon is created, then the equip event is called to equip it, which also gets sent to the client. Then the client gets the equip event, then the client gets the weapon create. (Notice the client weapon create is AFTER the equip event so it never gets equipped. It ends up sitting at 0,0,0 in the world usually.)

What you have to do is have a variable on the weapon like OwnerPlayer (and maybe also an EquipSocket variable) and make them replicated and make OwnerPlayer be Rep_Notify. Then right after the spawn on the server, set the OwnerPlayer (and EquipSocket if you have that too). In the Rep_Notify do the socket attachment.

Now just after the weapon gets created the rep notify gets called and it equips.

In The Dead Linger we set both an owning player and the equip socket.
In TheVOID there is only one possible socket so we don’t have that variable.