com.unity.netcode.gameobjects icon indicating copy to clipboard operation
com.unity.netcode.gameobjects copied to clipboard

re-parenting done during scene load doesn't sync to clients

Open zachstronaut opened this issue 1 year ago • 5 comments

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.

zachstronaut avatar Mar 28 '24 16:03 zachstronaut

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 avatar Apr 04 '24 19:04 zachstronaut

@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.OnLoadComplete on 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.OnLoad will 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.

Let me know if this helps resolve your issue?

NoelStephensUnity avatar Apr 09 '24 20:04 NoelStephensUnity

@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.

zachstronaut avatar Apr 10 '24 17:04 zachstronaut

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...

💯

NoelStephensUnity avatar Apr 10 '24 22:04 NoelStephensUnity

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

NoelStephensUnity avatar Apr 16 '24 14:04 NoelStephensUnity