How do I spawn an actor from a client?

Hi Grogger,

The best way to do something like this would be to have the client send an RPC to the server to request the server spawn the actor, which would then replicate to all the clients (including the client who requested the spawn, assuming the actor that was spawned was properly marked as replicated). This is how projectiles are spawned for example.

Let me know if this helps!

I am attempting to spawn an item from a client and have it replicated to all other clients, though items spawned from SpawnActor do not seem to replicate (unless it was called from the server).

What is the correct to spawn an actor from a client in UE4?

Thanks in advance!

Hi John, thank you for the response, that worked great!

The only problem I am having now is how to tell the client where the player controller can find this newly spawned actor so he could interact with it.

Is there are common way of doing this as well?

This can get a little tricky.

The simple way would be to send an RPC back to the client with a pointer to the spawned actor as a parameter. But, if the server hasn’t replicated this actor to the client yet (latency, lost packets, etc), this will end up being a NULL parameter when the client receives the RPC (this would be considered an unmapped actor parameter).

You could also store this as a property on the player controller, and the server could set it for the controller of the client who spawned the actor, and then client can react via OnRep notification when that property changed to know that the spawned actor has arrived. This can be tricky with multiple spawned actors though. In this case, the server could store it as a replicated array of actor references on the player controller for the client.

These are just a few ideas though. Basically, using RPC’s (to/from server), property replication (server to client only), and OnRep notifications, you can usually do what you need. The main thing to look out for is unmapped properties, which are most dangerous with RPC’s as mentioned above.

Thanks again John, this has been very helpful

Hey I tried it in a similar way:

  1. PlayerController calls ServerSpawnModifiable()
  2. ServerSpawnModifiable internally changes the replicated SelectedModifiable Property
  3. The OnRep method got called on client but the parameter NewSelection remains nullptr.

Strangely the SelectedModifiable Property is changed later somehow because the PlayerController is able to rotate the SelectedModifiable. Maybe I’m missing something like a flag!?

My Property:

UPROPERTY(BlueprintReadOnly, category = "Selection", ReplicatedUsing=OnRep_SelectedModifiable)
	AModifiableActor* SelectedModifiable;

My OnRep Method:
bool bProcessCamOffset = false;
FVector lastLoc(ForceInitToZero);

	if (SelectedModifiable) {
		bProcessCamOffset = bIntelligentCamera;
		lastLoc = SelectedModifiable->GetActorLocation();
	}

	// move to selected stone replicated:
	SelectedModifiable = NewSelection;

	if (bProcessCamOffset && SelectedModifiable) {
		FVector offset = SelectedModifiable->GetActorLocation() - lastLoc;
		FVector newPos = GetPawn()->GetActorLocation() + offset;
		GetPawn()->SetActorLocation(newPos);
	}

The Server-Side Spawning Method:

FTransform SpawnTM(rotation, location);
	AModifiableActor* NewActor = Cast<AModifiableActor>  (UGameplayStatics::BeginSpawningActorFromClass(this,  CurrentModifiableClass, SpawnTM));
	if (NewActor)
	{
		UGameplayStatics::FinishSpawningActor(NewActor, SpawnTM);
		Select(NewActor);
	}

And the Select method:

if (SelectedModifiable) 
	{
		SelectedModifiable->SetOwner(nullptr);
	}

	if (stone) {
		NewSelection->SetOwner(this);
	}

	OnRep_SelectedModifiable(NewSelection);

Although it’s not in the code above: I’m using ‘GEngine->AddDebugMessageOnScreen()’ to check the value of NewSelection, such that a timeout caused by debugger cannot be the reason for the nullptr.

Ok I got it!

SelectedModifiable is replaced with null because the Replication of the newly spawned Actor is slower. I use a RPC on the client side now that updates the ICam by only using the Location of the newly spawned Modifiable!