Spawning a Pawn and Possess()'ing it doesn't function properly in MP with replication

While originally attempting to fix a problem related to infinitely driving cars I started adapting the GTA Style Vehicle Interaction project (GTA Style Vehicle Interaction - Project File Included - Community & Industry Discussion - Unreal Engine Forums) and I ended up finding out that Possessing caused some issues.
This is a problem that occurs both in C++ as well as Blueprints.

Basically, possessing a pawn after spawning it results in a weird/invalid game state.
In case of the GTA project:

  • The vehicle is still sort of possessed and keeps processing the last input it received before Possess was called on the new pawn. However, since it is not really possessed, further input (such as releasing throttle) is never processed. As a result, it’ll keep on driving forever.
  • The player camera moves to the spawned pawn’s camera as if it’s being possessed, however it does not process any input.

I suspect this indicates a bug in pawn and controller replication, or rather, the order in which it replicates.

There are at least 2 workarounds that kind of work that you could use in the meantime but these aren’t workarounds for nothing :stuck_out_tongue:

  • When the previous pawn is destroyed before calling Possess() on the new pawn, everything works fine. This is also most likely the only reason why the RestartPlayer() function is working at the moment; it seems that by default it is only called after a player’s pawn has been destroyed.
  • When adding a delay between spawning and calling Possess() on the new pawn, everything works fine. This delay probably allows for the spawned pawn to replicate completely.

If you want to look at the GTA project (grab it here: Dropbox - GTAVehicleSetup.7z - Simplify your life), the asset of interest is Blueprint’/Game/Sedan/Sedan.Sedan’, Event Graph and then the node sequence attached to the ‘EnterVehicle’ Input Action. If an even smaller sample is needed I may be able to provide that later this week, or otherwise maybe next week.

References
Someone who had the same problem:

GTA Vehicle Interaction Project:

Hi Omar007,

I have been looking through your project and have a few things that I noticed:

  1. If you set the delay on your possession in blueprint sedan to .1, the time it takes to allow input drastically reduces and seems much more fluid.
  2. I don’t see any nodes that unpossess the vehicle when you get out of it. Try adding an unpossess node before the possess node for your primary pawn.

Yea that delay is the workaround to get it semi-working. However this workaround has some issues other than introducing a delay; depending on latency, the value of .1 may be to short and you still end up with the same problem.

The unpossess on the old pawn is called inside the possess function. I had already tried to add the unpossess node but that did not change anything at all. The issue persisted.

Have you tried temporarily disabling input when you first get out of the vehicle? You should be able to disable input then renable it on a delayed timer and it should stop the throttle.

I have. I also tried forcibly enabling brakes, reversing velocity etcetc, nothing worked.
The only way I managed to get it to ‘work’ is with the above workarounds.

When I attempted to debug the C++ code behind Possess, Controller’s OnRep_Pawn and Pawn’s OnRep_Controller, I noticed that the amount of times and order in which they executed changed when using the workarounds. I was unable to figure out how that happened/worked though.

This issue has definitely been rather difficult to nail down what may be causing it. Have you tried running an “is Valid” check before repossessing the new pawn?

I have now; the Is Valid check passes just fine…

And the issue is still occurring? I’m going to take another look as soon as I am able (it may be tomorrow or friday) to see if I can see what may be causing the error.

Yea the issue persists. Directly after the spawn the IsValid check works just fine and passes without problem, however possessing still doesn’t function properly.

1 Like

Ok, while I haven’t been able to figure out the camera situation quite yet, I did figure out how to stop the vehicle movement. When exiting the vehicle from the “Switch has authority” authority pin or the “server exit vehicle” exec pin, plug in a “set throttle input” and multiply the Axis value by -1. This sets the exact inverse of the throttle and causes the vehicle to slow to a halt after departing.

I guess that’d work as a temporary solution in the meantime.

However, if the core problem can be found, this should no longer be needed either as in that case the auto-brake should fire (if configured in the BP default properties ofc.) when the vehicle gets unpossessed. It is because the possessing bugs out here that the ‘auto-brake when upossessed’ doesn’t function properly either.

I’ll continue looking into this, however this should be a viable workaround in the meantime.

For stopping the vehicle, yes. However, this still leaves the other side of the issue; the new pawn. Only the camera moves to this new pawn. It never receives the input.
I can probably do some experimentation this weekend to see if I can find a workaround for that part of the issue as well.

Hi and Omar,

I have having similar issues using C++, my logic is sound (has to be, gone over it so many times) but I’m still experiencing the control bugs.

My thread on the forums is here with various links and a description of what should be happening. I’m about to give 4.7 a shot, but I doubt there will be much change.

https://forums.unrealengine.com/showthread.php?57797-No-client-control-of-newly-Posessed-Pawn-amp-general-possession-issues

1 Like

I just tested Omar’s project in 4.7, and it’s even worse. The Delay doesn’t fix the Possession anymore, so you still end up with no control over the Character as a client, with or without the delay!

Hi everyone,

I just wanted to drop in and let you know that we are still looking at this, I updated the forums with this information as well.

Ok, I finally got a chance to look at this in depth. Thank you for providing the test project, it was very helpful!

The good news is that everything can be made workable in the current release. I just tested with the latest 4.7 code, but I believe this should work in 4.6 as well.

The root of the problem is that you are calling Possess() on the client. This is not supposed to happen, although it’s our fault that we don’t message this or restrict this call. We will fix this in a future release (too late for 4.7 though). For now just make sure that you spawn Pawns on the server, and Possess() them there as well. This also explains why some people were asking why OnRep_Pawn() was not occurring on clients: they had already possessed it on clients, so they didn’t get the network notification because that only happens when the value changes.

The fact that you immediately destroy the character while there is a pending RPC or replication is also not good. If you really need to destroy the character, insert a delay. Typically in this scenario we suggest hiding the actor, disabling collision, and disabling ticking. Then when you exit the vehicle, place the actor where you need it, and re-enable all those things.

There is one engine bug that will be fixed for 4.8, but you can work around it, in blueprints or in code. The issue here is spawning an actor and then immediately calling Possess(). They can get to the client in the wrong order and the possession can fail. If you don’t spawn the pawn (because you hid it instead of destroying it), this isn’t an issue.

To work around this, in blueprints, you just need to insert a short delay between calling SpawnActor and then possessing it on the server (you already had this, this is just for general information).

The code fix is simple, in APlayerController::ClientRestart_Implementation():

	if ( GetPawn() == NULL )
	{
		ServerCheckClientPossession(); // <--- NEW CODE: make server resend pawn
		return;
	}

Here is an overall breakdown of the necessary Blueprint changes in your project:

Old character:

New character (possess on the server only, and don’t destroy the pawn):

Old sedan:

New sedan. Basically just only do stuff on the server. I left the SpawnActor node, but you could remove it if you don’t destroy the pawn, and then you can drop the yellow circled node which is the workaround for the engine code issue:

I hope this clarifies things, and thanks for bearing with us as we worked this out!

-Zak

1 Like

Hey Zak,

Sorry to post this in Multiple places but I believe I’ve found a Repro for an issue connected to this. See Answerhub Post Here: