At the moment, when executing this code:
auto actor = GetWorld()->SpawnActorDeferred<AActor>(
*ActorClass,
transform,
Owner,
Instigator,
ESpawnActorCollisionHandlingMethod::AlwaysSpawn);
You don’t have an opportunity to directly set properties on member ActorComponents, for instance calling: actor->FindComponent<USomeComponent>()
as they have yet to actually be registered. Trouble is, calling actor->FinishSpawning() will call BeginPlay() on those components we want to modify before we’ve set them up.
I have gotten around this problem with a bit of tomfoolery:
//Since I can't specifically request that begin play is deferred, hack it in!
bool bTemp = actor->bExchangedRoles;
ENetRole temp = actor->Role;
actor->bExchangedRoles = true;
actor->Role = ENetRole::ROLE_Authority;
actor->SwapRolesForReplay();
//causes this to be true:
//const bool bDeferBeginPlayAndUpdateOverlaps = (bExchangedRoles && RemoteRole == ROLE_Authority);
UGameplayStatics::FinishSpawningActor(actor, transform);
//Reset
actor->SwapRolesForReplay();
actor->bExchangedRoles = bTemp;
actor->Role = temp;
I am then free to modify any components I require before completly finishing the spawning process by calling actor->DispatchBeginPlay();
My proposal is to add another enum or bool to the FActorSpawnParameters structure along the lines of: spawnParams.bRequestDeferredBeginPlay = true;
which would result in full actor construction, but require the developer to call actor->DispatchBeginPlay()