Server not Calling OnRep Functions on Client

I am trying to spawn the characters equipment in my multiplayer game. From what I understand actor can only be spawned on the server or else the client-spawned actor will think it has ROLE_Authority.

So a little background, my character has a UActorComponent called “ArenaCharacterEquipment” which I want to contain all the characters gear.

In PostInitializeComponents on my character I check for Role == ROLE_Authority, so if its the server I want to spawn all the equipment. This works.

“ArenaCharacter.cpp”

void AArenaCharacter::PostInitializeComponents()
{
	Super::PostInitializeComponents();

	if (Role == ROLE_Authority)
	{
		CharacterEquipment->SpawnDefaultEquipment();
	}
}

“ArenaCharacterEquipment.cpp”

void UArenaCharacterEquipment::SpawnDefaultEquipment()
{
	FActorSpawnParameters SpawnInfo;
	SpawnInfo.bNoCollisionFail = true;

	PrimaryWeapon = GetWorld()->SpawnActor<AArenaWeapon>(PrimaryWeaponBP, SpawnInfo);
	PrimaryWeapon->SetOwningPawn(Cast<AArenaCharacter>(GetOwner()));
	PrimaryWeapon->SetPrimary(true);
	PrimaryWeapon->UnEquip();

	SecondaryWeapon = GetWorld()->SpawnActor<AArenaWeapon>(SecondaryWeaponBP, SpawnInfo);
	SecondaryWeapon->SetOwningPawn(Cast<AArenaCharacter>(GetOwner()));
	SecondaryWeapon->SetPrimary(false);
	SecondaryWeapon->UnEquip();
}

I set ReplicatedUsing on the Primary and Secondary weapon. However these are never called. When I play the game, the server spawns both his and the clients gear fine. However on the clients side no gear is spawned for him or the server.

“ArenaCharacterEquipment.h”

    UPROPERTY(Transient, ReplicatedUsing = OnRep_PrimaryWeapon)
	class AArenaWeapon* PrimaryWeapon;
	UPROPERTY(EditAnywhere, Category = Weapons)
	TSubclassOf<class AArenaWeapon> PrimaryWeaponBP;

	UPROPERTY(Transient, ReplicatedUsing = OnRep_SecondaryWeapon)
	class AArenaWeapon* SecondaryWeapon;
	UPROPERTY(EditAnywhere, Category = Weapons)
	TSubclassOf<class AArenaWeapon> SecondaryWeaponBP;

“ArenaCharacterEquipment.cpp”

void UArenaCharacterEquipment::GetLifetimeReplicatedProps(TArray< FLifetimeProperty > & OutLifetimeProps) const
{
	Super::GetLifetimeReplicatedProps(OutLifetimeProps);

	DOREPLIFETIME(UArenaCharacterEquipment, PrimaryWeapon);
	DOREPLIFETIME(UArenaCharacterEquipment, SecondaryWeapon);
}

void UArenaCharacterEquipment::OnRep_PrimaryWeapon()
{
	FActorSpawnParameters SpawnInfo;
	SpawnInfo.bNoCollisionFail = true;

	PrimaryWeapon = GetWorld()->SpawnActor<AArenaWeapon>(PrimaryWeaponBP, SpawnInfo);
	PrimaryWeapon->SetOwningPawn(Cast<AArenaCharacter>(GetOwner()));
	PrimaryWeapon->SetPrimary(true);
	PrimaryWeapon->UnEquip();
}

void UArenaCharacterEquipment::OnRep_SecondaryWeapon()
{
	FActorSpawnParameters SpawnInfo;
	SpawnInfo.bNoCollisionFail = true;

	SecondaryWeapon = GetWorld()->SpawnActor<AArenaWeapon>(SecondaryWeaponBP, SpawnInfo);
	SecondaryWeapon->SetOwningPawn(Cast<AArenaCharacter>(GetOwner()));
	SecondaryWeapon->SetPrimary(false);
	SecondaryWeapon->UnEquip();
}

This is really weird, no matter what I do I can’t get the OnRep functions to be called. I added break points and they are never hit.

What do your function definitions look like in your header file?

“ArenaCharacterEquipment.h”

public:

	//UFUNCTION(NetMulticast, Reliable)
	void SpawnDefaultEquipment();

private:

    UFUNCTION()
	void OnRep_PrimaryWeapon();

	UFUNCTION()
	void OnRep_SecondaryWeapon();

Thanks for the help. Just a couple of follow ups:

I am not sure what you mean by “single process” the debugged is set to “Debug Game Editor” and other OnRep functions are being trigger.

I tried to see if the values were in fact being replicated, unfortunately they aren’t and the client crashes anytime someone tries to access their weapons.

I always thought that spawning actors on the server automatically triggered it on the client, based on the how the “Shooter Game” does it. But for some reason for me when I spawn them on the server the client has no idea.

Here are my only thoughts, but I have no certain answers for you unfortunately :confused:

Are you running single process? If not your debugger might not be attached to the process where your functions will be getting called.

Are the values actually being replicated but the functions just aren’t called? Maybe chuck something in a tick function so you can just look at the values that should be replicated?

Unrelated, but if you spawn an actor on the server, it should also trigger it being spawned on the client. You shouldn’t need to spawn it manually in both places.

  1. “Run using single process” is in the launch settings of the game and lets you launch a separate process for every instance of your game when you’re running in PIE. It’s useful to test this way, but your debugger won’t be automatically attached to this process when they launch, so your break points wouldn’t get hit.

  2. Interesting. Have you tried moving your spawning stuff into BeginPlay instead of PostInit?

Try going into your play advanced settings and changing the editor multiplayer mode so that the editor is the client and the listen server is the other window. Then look in the World Outliner to see if the weapons are being spawned somewhere far away from your characters?

Hey, I know it’s a bit late, but I was getting the same issue and tried just about everything (I’m working on a game with a dedicated server) it wasn’t working in the editor because I didn’t have the dedicated server option ticked in the play settings.
Maybe this will help someone who comes to this post later.

I know my answer is also late. Here are my findings. When we are replicating a property If we bind an OnRep function to that property. That function apparently only gets triggered in the client. So each time that property gets replicated that onRep function will get triggered in the client. But not in the Server. So if you want to trigger that same functionality on the server. You check for the role authority of the particular pawn GetLocalRole() and if only the role is Role_Authority run the same functionality you try to run inside onRep function. Hope this will help someone.