com.unity.netcode.gameobjects
com.unity.netcode.gameobjects copied to clipboard
re-parenting done during scene load doesn't sync to clients
Re-parenting done during scene load doesn't sync to clients, it just silently fails. As best I can tell, there's no bool in NetworkManager that corresponds to this state. You have to subscribe to NetworkManager.SceneManager.OnSceneEvent yourself and implement your own bool.
The object I was re-parenting was IsSpawned == true but the re-parenting was still silently failing. It's possible the NetworkObject I was targeting as a parent was not itself IsSpawned yet and there was a race condition there?
NetworkBehaviour could have a virtual method that's like OnSceneSycned or OnPostNetworkSpawn something... it would be called after OnNetworkSpawn has completed for all scene spawned network objects.
@zachstronaut Yeah, that is a tricky one to solve for while in the middle of a scene loading event especially if you are handling the parenting within the OnNetworkSpawn method since it will be greatly dependent on both the parent and child/children being spawned before handling parenting.
A few things you could do:
- On the server/host side wait for the SceneEventTypes.OnLoadComplete event (if using OnSceneEvent make sure the client identifier is the same as the server/host so you know the event is local) and then handle parenting. Alternately, you can subscribe to
NetworkSceneManager.OnLoadCompleteon the server/host side.- For in-scene placed NetworkObjects, you can subscribe to loading related scene events within OnNetworkSpawn since they are spawned locally prior to the event being invoked. You would only want the server to subscribe for this scenario.
It would look like:
- InScenePlacedBehaviour.OnNetworkSpawn --> subscribe to
NetworkSceneManager.OnLoadComplete SceneEventTypes.OnLoadwill be sent to clients- They will begin loading the scene and spawning the in-scene placed NetworkObjects
- InScenePlacedBehaviour.OnLoadComplete --> parent NetworkObject(s)
- Message is sent to clients and either deferred (will hold for NetworkConfig.SpawnTimeOut period of time) or if the client has already finished the event it will be processed.
- If deferred, upon the scene load event completing the client will then process any pending/deferred messages and the locally spawned NetworkObject(s) should get parented.
- Message is sent to clients and either deferred (will hold for NetworkConfig.SpawnTimeOut period of time) or if the client has already finished the event it will be processed.
- InScenePlacedBehaviour.OnNetworkSpawn --> subscribe to
- For in-scene placed NetworkObjects, you can subscribe to loading related scene events within OnNetworkSpawn since they are spawned locally prior to the event being invoked. You would only want the server to subscribe for this scenario.
It would look like:
Let me know if this helps resolve your issue?
@NoelStephensUnity yes, I solved it via creating my own callback from a scene event handler sort of like your suggestion.
I think it is a bug though that re-parenting can silently fail.
And consider it a feature request for all NetworkBehaviours to have both an OnNetworkSpawn and also some sort of OnPostNetworkSpawn ... consistent with Awake()/Start() and how having those be separate allows for avoiding a certain type of race condition.
And consider it a feature request for all NetworkBehaviours to have both an OnNetworkSpawn and also some sort of OnPostNetworkSpawn ... consistent with Awake()/Start() and how having those be separate allows for avoiding a certain type of race condition.
Similar to my previous replay in your other filed issue, I am very much in alignment with:
- PreSpawn --> Invoked on all NetworkBehaviours on all NetworkObjects (first)
- Spawn --> Invoked on all NetworkBehaviours on all NetworkObjects (second)
- PostSpawn --> Invoked on all NetworkBehaviours on all NetworkObjects (third)
It provides the opportunity to handle:
- Pre-spawn configuration
- Spawn initialization (which could have pre-spawn dependencies)
- And what I think has definitely been missing:
- Post-Spawn actions without having to worry if a certain NetworkObject is spawned or not (which includes its NetworkBehaviours). (i.e. parenting, invoking an Rpc on a different NetworkObject's NetworkBehaviour, etc...
💯
This is a user pain area so leaving as bug but also marking it as a feature. Note for implementation: Target v2.0.0 and back port to v1.x.x