AgentNolan not holding the AssaultRifle in Demo Scene

conraddu

Member
Hello,

While developing my own multiplayer game with the Third Person Controller and PUN integration, I noticed an issue with AI's weapons not appearing in their hands in a certain workflow.

The workflow is as follows:
1.) The room is created by a client, making them the master client
2.) A second client joins the room
3.) The master client leaves the room
4.) Another client boots up and joins the room

The client at step 4 in this workflow will see AI agents without equipped items. For instance, following these steps in the PUN Add-on's demo scene will lead to the client who joined at step 4 seeing AgentNolan walk around without his gun, but still aiming as if he was holding it.

I was trying to think of why this would be a problem for AI agents only, and not players. Players all have their weapons equipped per normal. My leading suspicion is with the Runtime pickups. I have always been a bit confused by the Runtime pickups for the reason that the Runtime Pickups component on the PunGame object in the Pun Add-on demo scene only has two items in it (BowPun & KatanaPun) which seems really odd. The naming of these objects also makes me think there is something special with their components in regards to PUN. But I don't think that's the case.

Any help on this would be much appreciated!
 
After further investigation it appears to be an issue with how ownership of AI is transferred between master clients. After master client is transferred, the new master client doesn't know its supposed to call PunCharacter.OnPlayerEnteredRoom for the AI agents.

So when a new client joins the room, a break point is only be triggered in PunCharacter.OnPlayerEnteredRoom for the player (master client) currently in the room, not for the AI.

I believe the solution here is to register the AI Agents OnPlayerEnteredRoom in the event handler after the player becomes the owner of the AI agents due to master client transfer. But this does worry me that other things could be missing in this transfer process, since PunCharacter's start function is quite involved with event registration.

Any other ideas on a solution for this problem?
 
Okay my solution at the moment is to override the OnMasterClientSwitched alongside the other overrides in SpawnManagerBase, and then in PunCharacter I register the events (that are specific to the master client) in the callback function of OnMasterClientSwitched :)

There remains an issue with the rotation of agents in this same workflow. I noticed that when a client connects after a master client has transferred ownership, an idle agent will have some default rotation applied to them, rather than the actual rotation seen on the master client.

In the first few frames on the new client, I can see the agents more or less "teleport" to their correct positions (according to the master client). It seems odd that position would be set correctly but rotation wouldn't be. I would also like to clean up this "teleporting" like behavior, so that clients cant see agents repositioning themselves during the first few frames of the game.
 
Thanks for posting your (partial) solution. I will take a look at this for the next update.
 
That would be great thank you. Do you have any recommendations on where I should look for this rotation problem? The client isn't being sent a rotation for the AI matching the rotation of the AI on the master client. This only happens after master client is transferred. I have been going a bit crazy digging through the PunCharacterTransformMonitor. Based on what I am seeing, the dirty flag is set for position but not rotation when a new client joins. But figuring out why that dirty flag isn't being set is rather difficult.
 
It has been awhile since I last looked at that code and I need to properly set breakpoints to debug this, but the initial player data is set within the data of the PlayerInstantiation event within the SpawnManagerBase.
 
So unless I am mistaken, the PlayerInstantiation event in the SpawnManagerBase is just for player controlled characters. The issue with rotation (and occasionally position) not being set is only with AI agents. My AI agents exist in the room as prefabs already when the game begins.
 
Ah, yes, you're right. In that case the PunCharacterTransformMonitor is responsible for the initial sync state. The rotation dirty flag should be set on the first frame and transmitted to the client.

Looking at the code though m_NetworkRotation is set to the transform's rotation so if the rotation doesn't move then the dirty flag isn't set. Is that what you are experiencing?
 
Yes I was looking at that too. If there is no rotation or position change, then the master client won't know to send the AI's position data to the other clients who may have just connected. So if the AI is staying completely still, newly connected clients won't know where they are.

The reason that the position gets updated occasionally is because when a client first connects to the master client, the AI agent gets a really small position change in the y-axis. I noticed this when I break-pointed in the dirty check of the position during the write stream of PunCharacterTransformMonitor. The oddest part is that this only happens for the first client to connect to the master client. I don't know why a client connecting to the game would cause the AI agent to slightly adjust its height (fall ability?). And none the less why this is only a problem for the first client who connects.
 
Alright, so what I ended up doing was registering the OnPlayerEnteredRoom event for the master client in the awake function of PunCharacterTransformMonitor. I then set a flag like forceSendTransformData to true in the OnPlayerEnteredRoom callback. Then when I am checking if the data is dirty in the write stream, I also check this flag.

I also registered the OnMasterClientSwitched event so that only the master client can register the OnPlayerEnteredRoom event, to reduce the amount of useless calls that the non-master clients would be making whenever players enter the room.

This works! I am not sure if its the best solution, but it most certainly solves the problem. I will probably also set the character to the position and rotation when the forceSendTransformData flag is true instead of relying on the update function to interpolate the position. That way you don't see ai agents shift their way over to their correct positions at the start of the game.
 
Thanks for posting your solution - it'll help when I am debugging it and coming up with a fix for the next update.
 
Top