Download

Does the Non-Local Client Pawn ever call PossessedBy()?

Does the Non-Local Client Pawn ever call PossessedBy()?

Initialization is suppose to spawn and attach a series of child actors to the pawn.
Currently I have initialization in PossessedBy(), and it mostly works. Every pawn properly initializes except the CLIENT side version of the SERVER player’s pawn.
I put a debug message in PossessedBy() behind an if (Role < ROLE_Authority && !IsLocallyControlled()) filter to check if the non local pawn is calling PossessedBy(), but the message never appears.

All of the child actors for the non local pawn are spawned and visible on the CLIENT(presumably because of replication that occurs when an actor is spawned), but because PossessedBy() is never called the child actors are not attached to the non local pawn.

I am doing my testing in the “Play Stand Alone Game” option, and the Client joins the Server after a bit of a delay. So the Server Player’s Pawn has already spawned and initialized by the time the Client joins.
What function should I use to ensure that Initialization always occurs after possession on both Server and Client?

No, because the Controllers don’t exist on a client. Pawns on a Client don’t know who they’re possessed by, other than their own Pawn.

Also, Pawn.h comment explains it too:



	/** 
	 * Called when this Pawn is possessed. Only called on the server (or in standalone).
	 *  @param C The controller possessing this pawn
	 */
	virtual void PossessedBy(AController* NewController);


As for your use-case, you should spawn the Child Actors on the Server and Attach them to the Pawn. So long as the Child Actors replicate, they and their attachments will copy down to clients.

Spawning the Child Actors, and attachment of said actors, on the SERVER was how I was doing it originally. But the attachment was not happening on the CLIENT, which is why I was trying to manually attach them on the CLIENT in the first place. But I will revert and try again. Perhaps I messed something up previously.

Meanwhile I have two further questions:
1.
If the Child Actor’s attachments are suppose to be replicated when they are, what would cause the attachments to NOT replicate? Is there a variable I have to set somewhere?
(I already set bReplicates to true, maybe there is something else I missed? This is what I have in the constructor:
SetRemoteRoleForBackwardsCompat(ROLE_SimulatedProxy);
bReplicates = true;
bReplicateMovement = true;
bAlwaysRelevant = true;
bNetLoadOnClient = true; )

The CLIENT doesn’t immediately join the SERVER, meaning the Child Actors on the SERVER have nothing to replicate to initially. I noticed that the Spawning of said Child Actors on the CLIENT happens(without any extra input from my code) at some point when the CLIENT does join the SERVER. Are attachments also handled like they are supposed to in this case? (when the CLIENT is “late” in joining the SERVER)

If they are Replicating Movement, then Attachments should work out of the box (the attachment data is part of the FRepMovement struct). However, I haven’t tested to see if that works with Child Actor Components. It probably doesn’t. Also, you don’t need to have the following in the constructor:



SetRemoteRoleForBackwardsCompat(ROLE_SimulatedProxy);
bNetLoadOnClient = true;


And yes, the components will be spawned client-side when they join, and will attach if they’re supposed to.

What you’re basically building is no different to a weapon or inventory system. I’d suggest checking out the ShooterGame example to see how Epic handles this.

Currently each Child Actor has a base component chain of:

USphereComponent (RootComponent) > UStaticMeshComponent A > UStaticMeshComponent B

There is a “Core” Child Actor that is Attached to the Pawn’s RootComponent(Capsule Component).
All the rest are attached to UStaticMeshComponent A of either that “Core” Child Actor, or to another Child Actor already attached to the “Core”.

If attachment replication doesn’t work on Child Actor components, would that explain the failure with this setup?