I am having an issue where the Host player is spawning as soon as the scene changes but before the world is ready, using ApprovalCheck to set the player prefab and CreatePlayerObject
I have been trying a few different things to resolve this including what I expected to be the solution by using Network SceneManger events (LoadEventCompleted) to delay joining using Response Pending = true / false.
But this does not seem to work, the host player spawns before the LoadEventCompleted, the host player has the correct Skin and is created, but it is like the “response.Pending = true;” is ignored for the host?
Any ideas here or maybe a thought on another way to spawn the host player after the scene change?
public class NetworkGameManager : MonoBehaviour
{
NetworkManager.ConnectionApprovalResponse StoredResponse;
…
response.Approved = true;
response.CreatePlayerObject = true;
// If additional approval steps are needed, set this to true until the additional steps are complete
// once it transitions from true to false the connection approval response will be processed.
response.Pending = true;
StoredResponse = response;
}
You didn’t post the code where you load the scene. Perhaps you only do so after the player has spawned, eg in OnNetworkSpawn rather than right after StartHost?
Here in the logs can see the order, start host, host spawn, scene load events.
I have also found that if i commend out Response.Pending = false the ConnectionApproval is still immediately processed.
Changing other values such as response.CreatePlayerObject = true; does work in the ConnectionApproval callback.
It almost looks like the ConnectionApproval.Pending is not evaluated for a host so using this technique to delay a host spawn might not work? I reviewed the Netcode code but couldn’t quite follow the logic for pending retries on host vs client connections.
I’ve been running through the NetworkConnection code in the debugger and I am pretty sure the Host Player is not handled the same as connecting clients in regards to ConnectionApproval.Pending retries.
Is there a best practice here I am missing when spawning in the Host Player that needs to be deferred until the scene loading is complete?
Is this a bug?
My current thought here is to “Respawn” the Host player when the Network Scene loaded event fires but that seems like a workaround to just delaying the ConnectionApproval handled spawn?
Do we have someone from Unity who can shed some light here?
I have been able to get a bit closer by looking up the prefab from the network list using the ConnectionApproval data inside of the LoadEventCompleted Event. Not quite perfect, but promising.
Seeing how often, and particularly in such a convoluted way you use GameObject.Find(“”) I refuse to offer more help.
It seems very likely that the issue is buried somewhere in “finding” objects. You don’t do so. There’s two rules about Find which is: don’t use it and don’t you dare to even think of using it! You’ll find plenty of reasons and alternatives if you look around.
And the reasons are all the more relevant in a networked game because the same object can have different names for different clients.
I did a little digging into this and you’re correct, the host is immediately approved and the Pending flag is ignored which makes sense I guess as the host can’t be denied approval. I didn’t see a way of controlling when the host is spawned.
I did some testing looking at scene event and spawn timing and knocked up this class, it’s rather specific/inflexible but might help with what you’re after:
One thing I did notice, on the client the host player is spawned before the scene SynchronizeComplete event, I don’t know whether or not that matters.
Thanks for that example. It reinforces some things which I was guessing at. I bet someone will find this useful in the future!
If feels there could be some improvement in Netcode here with host player spawning. I’m not sure of a use case for when you would want the host’s prefab to spawn before the scene is ready and here we document two cases of why you would want to delay the host spawn until after the scene is ready.