Why is there no on possessed event for client?

There is this big gap in ue4 framework due to which there is no way to know when a pawn is possessed on a client reliably at that exact moment!

I want to run a function on client as soon as the pawn is possessed by a player on start of the game.

The PossessedBy event is fired only on the server that too long before the client version is even spawned on the client , if you make any RPC to the owning client to notify at this time you’ll get a null controller since its not possessed on the client yet.

On the other hand there seems to be no event on the controller to notify it has possessed a pawn either.

If you put a timer you either make miss it if loading takes too long or keep the player waiting if the game loads too fast. This is really bad scenario

1 Like

I believe you can create a bool for bIsPosessed and set replication to be repNotify to get your desired outcome. You can set bIsPossessed on the server side and once each client receives the update, they will call the repNotify function and you can then call the event or further functionality from there.

1 Like

Nah mate! The solution is to override the restart function in APawn

3 Likes

Could you please explain this in more detail? I also have the problem that I get a null controller in that case.

Please see the following:

the function restart is called on client when it’s possessed atleast when it’s spawned for the first time by game mode. I can’t say if it’s called when it’s unpossessed by a controller and then possessed by another but when it’s spawned by AGameMode it is definitely called on the client and when it is called you’ll have a controller available on it

4 Likes

I tested this and it works fine. Thank you.

Yo. I am having a problem with OnRep_Pawn. It triggers immediately when the game starts, but when I change a client’s pawn later by calling possess on the server, OnRep_Pawn doesn’t get called anymore. I checked the Pawn-variable of the client’s controller on both server and the client itself: it changes to the new pawn correctly. And there is no call to OnRep_Pawn…

edit: just noticed this wasn’t the topic I wanted to reply to… but since it’s also pretty much on-topic, i’m gonna leave this here as well.

No need to override APawn::Restart

just get notified directly in player controller method
virtual void AcknowledgePossession(class APawn* P) override;

3 Likes

Hi,

EDIT: my answer only works for controller changed, not as a substitute of OnPossessed. For that you should use Restart as mentioned.

There are several options to let the client know when a Pawn has been possessed.

You can either use the BlueprintImplementableEvent “ReceiveControllerChanged”, bind to the Delegate “ReceiveControllerChangedDelegate” or override “NotifyControllerChanged”.


	/** Event called after a pawn's controller has changed, on the server and owning client. This will happen at the same time as the delegate on GameInstance */
	UFUNCTION(BlueprintImplementableEvent)
	void ReceiveControllerChanged(AController* OldController, AController* NewController);

	/** Event called after a pawn's controller has changed, on the server and owning client. This will happen at the same time as the delegate on GameInstance */
	UPROPERTY(BlueprintAssignable, Category = Pawn)
	FPawnControllerChangedSignature ReceiveControllerChangedDelegate;

	/** Call to notify about a change in controller, on both the server and owning client. This calls the above event and delegate */
	virtual void NotifyControllerChanged();