Download

Network client renders its own pawn, but bOwnerNoSee is true

I made a standalone build and deployed it to two machines. One machine hosted a game and the other machine joined. On the client machine, it’s rendering its own pawn, even though bOwnerNoSee=true on all renderable components in that pawn’s blueprint. (No client should ever render its own pawn.)

I added a bunch of logging to verify that the pawn has a valid owner, that the owner is correct, and that bOwnerNoSee is in fact true. I’m logging that stuff in Tick in case it ever changes. But the values are all correct, and they never change. Still, the pawn renders.

Weirdly, this only occurs under this particular networking scenario. If I run a host and client in PIE (by setting the number of players to 2 in the PIE settings dropdown) the issue also does not occur. The issue only occurs if my client and host are running in distinct processes (it doesn’t matter if they’re on different physical machines or running on the same machine).

I’m… kind of at a loss. Are there other things that could affect this, that could override/ignore the bOwnerNoSee flag?

(Side note: it’s kinda frustrating how I get different net sync results between two physically separate machines vs two standalone instances on the same machine vs two PIE instances. Makes things real difficult to debug…)

Check the view target of the player camera manager, player controller etc too, see if they match up.

The view target and ownership all appear to be correct across the board.

Adding this to my BeginPlay fixes the problem. I don’t understand why I needed to do this – it seems like exactly what bOwnerNoSee is supposed to already be doing – but it does work:


TInlineComponentArray<USceneComponent*> components(this);
for(USceneComponent* component : components)
{
	if(IsLocallyControlled())
	{
		UPrimitiveComponent* primitive = Cast<UPrimitiveComponent>(component);
		if(primitive && primitive->bOwnerNoSee) { primitive->bVisible = 0; }
	}
}

I have had a really odd issue with this before, but it was related to something different.

I was attaching my first-person mesh to the Player Controller instead of the Pawn (the game has a lot of active pawns at any one time, and I wanted to save time on Bone Updates and Scene Component Transform updates - only the local player ever needs to see a cockpit). I was finding that despite setting visibility of the mesh in the constructor, the mesh would always be hidden no matter what.

After much loss of hair and cursing, I discovered that I had to add this - because the Player Controller messes with visibility of it’s own components somewhere along the line:



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

	// Somehow, this makes this work. Absolutely NO idea how..
	GetFirstPersonMesh()->SetOnlyOwnerSee(false);


As you can see from the comment I still don’t fully understand why I needed to do this - but it was a nightmare to track down. Perhaps it’ll help you find the cause or at least code in a workaround.