SpawnActorDeferred with replication!

I though if I used the deferred method to spawn and actor, the actor in question would be created (and replicated) with the changes made to it.
However I’m having trouble with it.


void UWeaponSystemComponent::SpawnDefaultInventory(){
   if (GetOwnerRole() == ROLE_Authority){
      for (auto WeaponClass : DefaultInventoryClasses){
         AWeapon* NewWeapon = GetWorld()->SpawnActorDeferred<AWeapon>(WeaponClass, FVector(), FRotator(), GetOwner(), GetOwner()->Instigator);
         
         AddWeapon(NewWeapon);
         UGameplayStatics::FinishSpawningActor(NewWeapon, NewWeapon->GetTransform());
      }
   }
}

void UWeaponSystemComponent::AddWeapon(AWeapon* Weapon){
   if (Weapon && GetOwnerRole() == ROLE_Authority ){
      // set the owner of the inventory/weapon
      Weapon->OnEnterInventory(Cast<ASoldier>(GetOwner()));

      Inventory.AddUnique(Weapon);

      // if no weapon is currently is equipped, equip this one
      if (CurrentWeapon == NULL){
         EquipWeapon(Weapon);
      }
   }
}

On server side everything works as planned, the weapons are created with owner associated with them. However on the client, the weapons are created without owner, which is only replicated after its creation. Is my assumption wrong about the replication of actors creating using the deferred method?

I am going all necro on this thread because I am having the same issue. I’ve built my project starting from the ShooterGame example and when I spawn projectiles they are supposed to set a bunch of their parameters based on their owner during PostInitializeComponents, it works fine on the server, but on the clients the projectiles say they do not have an owner.

How do I give the inherited value Owner a replication notification function?

I think the problem arises when host(server) takes the cake, cut it and tried to share it. All these take several ticks before everyone (clients) managed to get a cut. Host being host will have the first cut at the cake. So before you can put some cherries (parameters/variables) on top, there must be a cake served to you (client).

I am using tick function to verify the existence of the cake but not sure if that is the correct approach.

SpawnActorDeferred is supposed to allow you to set some of the actor’s properties, before Construction scripts are executed (those happen after FinishSpawningActor), but the replication you need to do yourself, in case you need.
For example:


void UWeaponSystemComponent::SpawnDefaultInventory()
{
   if (GetOwnerRole() == ROLE_Authority)
   {
      for (auto WeaponClass : DefaultInventoryClasses)
      {
         AWeapon* NewWeapon = GetWorld()->SpawnActorDeferred<AWeapon>(WeaponClass, FVector(), FRotator(), GetOwner(), GetOwner()->Instigator);
         
         // Always make sure actor was created
         if (NewWeapon)
         {
              // AActor->Owner is replicated
              NewWeapon->SetOwner(SomeOwner);

              // Run construction scripts
              UGameplayStatics::FinishSpawningActor(NewWeapon, NewWeapon->GetTransform());
         }
      }
   }
}

Since AActor::Owner is replicated, this property will be replicated to the clients.

2 Likes