Actor spawned between client and server with different parameters

I’m spawning a replicated actor on the server and it’s correctly spanwed on the client as well, but without the parameters set to what I’ve set on the server.

// MyCharacter.h
UCLASS()
class MYPROJECT_API AMyCharacter : public ACharacter
{
	GENERATED_BODY()

public:
	UFUNCTION(Server, Reliable, BlueprintCallable)
	void Server_SpawnRandomWeapon(int32 ActualBullets);
}

// MyCharacter.cpp
void AMyCharacter::Server_SpawnRandomWeapon_Implementation(int32 Ammo)
{
	ABaseWeaponInteractable* DroppedWeapon = GetWorld()->SpawnActorDeferred<AWeapon>(InteractableWeaponClass, GetActorTransform());
    // setting my custom property
	DroppedWeapon->Ammo = Ammo;
	UGameplayStatics::FinishSpawningActor(DroppedWeapon, GetActorTransform());
}

But as can be seen in the BeginPlay of my spawned actor, Ammo has a different value between client and server

// Weapon.h
UCLASS()
class MYPROJECT_API AWeapon : public AActor
{
	GENERATED_BODY()

public:
	UPROPERTY(BlueprintReadWrite)
	int32 Ammo = 0;
}

// Weapon.cpp
void AWeapon::BeginPlay()
{
	Super::BeginPlay();

	if (HasAuthority())
	{
        // prints the value passed from Server_SpawnRandomWeapon
		UE_LOG(LogTemp, Warning, TEXT("Server: %d"), Ammo)
	}
	else
	{
        // prints 0 since that's the default value set in the header file
		UE_LOG(LogTemp, Warning, TEXT("Client: %d"), Ammo)
	}
}

This is driving me a little crazy! I feel I have a decent understanding of replication, but I’m clearly missing something. The actors are all marked as always relevant and replicated. Help’s appreciated!

1 Like

I literally haven’t worked with Replication for more than a minute or two in UE4, but I did a ton of it in UE2 and UE3 … so… don’t you have to also replicate the variables that you need?

I don’t believe I need to when the values are set before spawn, which is why I’m using SpawnActorDeferred. I don’t need the values to replicate once the actor is spawned; I just want the initial values to be the same between the server and client version of the actor

hmm. I’ve not used SpawnActorDeferred (a curious function, apparently allowing you to set properties before BeginPlay is called) but it looks like properties wouldn’t be replicated just by virtue of setting them prior to BeginPlay, I would be curious to know if it’s intended to work that way, though.

Reading elsewhere suggested it was supposed to work that way, or so I interpreted. Since actor spawning is fully replicated, I assumed the actor, when replicated to the client, would bring over the same intitial values.

Conceptually, I thought it was looking at the “instance” of the class on the server when replicating the spawn to the client. The behavior I’m exeriencing suggests that’s not the case; it’s just instantiating the actor on the client without any regards to the details of its instantiation on the server.

If SpawnActorDeferred's only use is to set instance variables before BeginPlay, I guess that makes sense. It’s a shame, though, because I don’t want this variable replicated. I just want to control its initial value when spawning on the server

per Conditional Property Replication | Unreal Engine Documentation

I think you would want DOREPLIFETIME_CONDITION with COND_InitialOnly

Assuming that there’s not been any major changes to replication since UE3, you only get the default properties of the spawned item, which is often a good reason to use a lot of blueprints for similar items that have differing properties, versus replicating properties.

i’m also not sure if that would work with SpawnActorDeferred, or if you’d get the initial replication during constructor, rather than after FinishSpawningActor. That might be worth testing and reporting back on :slight_smile:

Using COND_InitialOnly seems to work with SpawnActorDeferred. The actor seems to have the server value of the property in the client’s BeginPlay.

Thank you for your suggestion!

great to know, I do hope to end up on a multiplayer project in the future :smiley: and so i’ll need to eventually get into replication again.

So, you are setting the actor and the variable up to be replicated, and the variable is COND_InitialOnly, and it does perform the replication after FinishSpawningActor.