How do I use OwnerNoSee and OnlyOwnerSee in multiplayer?

I am working on a multiplayer FPS game right now, but I’m currently stuck trying to get players to only see what matters to them (i.e. only the first person mesh for the locally controlled player, only the third person meshes for everyone else). In begin play, I am spawning in a first person weapon and a third person weapon with the following code:

void AKnoxiousCharacter::SpawnDefaultWeapon()
{
	if (TEMP_WEAPON_CLASS)
	{
		FActorSpawnParameters SpawnParameters = FActorSpawnParameters();
		SpawnParameters.Instigator = this;
		SpawnParameters.Owner = this;
		SpawnParameters.SpawnCollisionHandlingOverride = ESpawnActorCollisionHandlingMethod::AlwaysSpawn;

		AWeapon* SpawnedFPWeapon = GetWorld()->SpawnActor<AWeapon>(
			TEMP_WEAPON_CLASS,
			FTransform(),
			SpawnParameters
			);

		AWeapon* SpawnedTPWeapon = GetWorld()->SpawnActor<AWeapon>(
			TEMP_WEAPON_CLASS,
			FTransform(),
			SpawnParameters
			);

		if (SpawnedFPWeapon)
		{
			SpawnedFPWeapon->AttachToComponent(Mesh1P, FAttachmentTransformRules(EAttachmentRule::SnapToTarget, true), GripPointSocketName);
			FPPrimaryWeapon = SpawnedFPWeapon;
			FPPrimaryWeapon->SetOwner(this);
			FPPrimaryWeapon->SkeletalMeshComp->SetOnlyOwnerSee(true);
		}
		else
		{
			UE_LOG(LogTemp, Error, TEXT("%s could not spawn default weapon!"), *(GetName()));
		}

		if (SpawnedTPWeapon)
		{
			SpawnedTPWeapon->AttachToComponent(GetMesh(), FAttachmentTransformRules(EAttachmentRule::SnapToTarget, true), GripPointSocketName);
			TPPrimaryWeapon = SpawnedTPWeapon;
			TPPrimaryWeapon->SetOwner(this);
			TPPrimaryWeapon->SkeletalMeshComp->SetOwnerNoSee(true);
			TPPrimaryWeapon->SetActorRelativeLocation(FVector(0.0f, 0.0f, TPPrimaryWeapon->GetVerticalGripOffset()));
		}
		else
		{
			UE_LOG(LogTemp, Error, TEXT("%s could not spawn default weapon!"), *(GetName()));
		}
	}
	else
	{
		UE_LOG(LogTemp, Error, TEXT("%s does not have a TEMP_WEAPON_CLASS defined!"), *(GetName()));
	}
}

This code is executed in begin play only when Role == ROLE_Authority. The AWeapon class has SetReplicates(true); in its constructor, the variables FPPrimaryWeapon and TPPrimaryWeapon are replicated using the UFUNCTION() macro and DOREPLIFETIME in GetLifetimeReplicatedProps(), and the SkeletalMeshComp in the AWeapon class is set to replicate in the same manner. I’ve double-checked all of the checkboxes to make sure that it wasn’t a saved variable from before the hot-reload, and everything looks like it’s in order, and on the Server instance everything works as intended–he only sees his first person mesh/weapon and others’ third person meshes/weapons. On any clients, however, they see both meshes as well as both weapons.

In the code block above I am explicitly setting FPPRimaryWeapon->SkeletalMeshComp->SetOnlyOwnerSee(true), and according to my understanding since that component is set to replicate, then that change should propagate to all clients and it should be set as such for all clients, but when I click on the weapon in the editor after depossessing, it shows that it is very clearly not set. I’m assuming this has something to do with me spawning the weapons on the server, because it works there, but I’m still new to UE4 networking so I could be way off.

I have no idea why this is happening, but if anyone has a solution or a better way to go about this it would be greatly appreciated! Thanks!

P.S. If you need any more information let me know and I can post it. Thanks!

I know this is an old post, but I ran into the same problem and decided to share my solution.

bOwnerNoSee and bOnlyOwnerSee variables do not replicate, so if you need to change their value, do it in some function that both the client and the listen server execute.

The issue for me was that I tried to change these values in a server-only function. So I moved the code to another function OnEquipped() which I call from a PostReplicate() function when my equipment list gets replicated.

1 Like