Since moving to 4.6.1 possession of a players pawn fails frequently in our multiplayer game.
I’ve confirmed this by migrating our code back to 4.5.1 and used the same situations/scenarios that were causing the player to not gain possession of their pawn in 4.6.1 only to have it work every time.
Is there anyone at Epic who can possibly point me in the direction of changes that could have affected pawn possession over a network? Perhaps there’s a change that I’m unaware I need to make?
Reading the release notes possession is only mentioned once, and in a comment, but something clearly has changed.
When the player respawns and ClientRestart is called on the server the pawn has a value but on the client the pawn passed into ClientRestart is NULL when it is initially called.
When called the second time (automatic retry) the pawn is NOT NULL and the controller is able to successfully possess it.
Just to further confirm that this is what’s happening I added a ClientMessage call right after the call to ClientRestart. The name of the Pawn comes through just fine.
It should also be noted that in fact the very first ClientRestart call when a player joins also fails, but the retry is called instantly. Looks like attempting to pass it that first time is where the issue lies…
Forgot to add as well that the pawn exists on the client and in fact has the same name as it does on the server, just cannot control it.
This also does not occur in the editor with dedicated server selected. This only occurs when running the server and client outside of the editor.
Willing to put the project up somewhere so someone at Epic can take a look if needed.
Hi overlawled, as you probably saw John Pollard suggested on the forum you try something with async loading. I also want to see if something we’ve changed since 4.6 fixes this for you. In APlayerController::ClientRestart_Implementation() there is a line that checks if the pawn is null and just returns, replace it with this:
if ( GetPawn() == NULL )
// We failed to possess, ask server to verify and potentially resend the pawn
Unfortunately neither this nor the other suggestion fixed this. I’ve done more digging and below is the relevant log messages from that digging.
Most important to note is that it appears that at some point immediately after the first APlayerController::ClientRestart after death the client DOES get a reference to the correct pawn but doesn’t acknowledge it with the server.
This reference to the pawn is provided by AController::OnRep_Pawn() but is not acknowledged, and as a result of it not coming through APlayerController::ClientRestart APawn::SetupPlayerInputComponent is never called which is why the player does not gain control of the pawn.
That change makes some sense, but I’d like to dig in to why things are broken. There has always been some cause for concern since variable replication can lag behind function replication. The call to ServerCheckClientPossession() should handle the case where the Pawn came over as null, and ask for the server to re-call the method. It’s concerning that this appears to be broken.