@@ -308,15 +308,18 @@ internal void OnValidate()
308308 /// </remarks>
309309 private void CheckForInScenePlaced ( )
310310 {
311- if ( PrefabUtility . IsPartOfAnyPrefab ( this ) && gameObject . scene . IsValid ( ) && gameObject . scene . isLoaded && gameObject . scene . buildIndex >= 0 )
311+ if ( gameObject . scene . IsValid ( ) && gameObject . scene . isLoaded && gameObject . scene . buildIndex >= 0 )
312312 {
313- var prefab = PrefabUtility . GetCorrespondingObjectFromSource ( gameObject ) ;
314- var assetPath = AssetDatabase . GetAssetPath ( prefab ) ;
315- var sourceAsset = AssetDatabase . LoadAssetAtPath < NetworkObject > ( assetPath ) ;
316- if ( sourceAsset != null && sourceAsset . GlobalObjectIdHash != 0 && InScenePlacedSourceGlobalObjectIdHash != sourceAsset . GlobalObjectIdHash )
313+ if ( PrefabUtility . IsPartOfAnyPrefab ( this ) )
317314 {
318- InScenePlacedSourceGlobalObjectIdHash = sourceAsset . GlobalObjectIdHash ;
319- EditorUtility . SetDirty ( this ) ;
315+ var prefab = PrefabUtility . GetCorrespondingObjectFromSource ( gameObject ) ;
316+ var assetPath = AssetDatabase . GetAssetPath ( prefab ) ;
317+ var sourceAsset = AssetDatabase . LoadAssetAtPath < NetworkObject > ( assetPath ) ;
318+ if ( sourceAsset != null && sourceAsset . GlobalObjectIdHash != 0 && InScenePlacedSourceGlobalObjectIdHash != sourceAsset . GlobalObjectIdHash )
319+ {
320+ InScenePlacedSourceGlobalObjectIdHash = sourceAsset . GlobalObjectIdHash ;
321+ EditorUtility . SetDirty ( this ) ;
322+ }
320323 }
321324 IsSceneObject = true ;
322325
@@ -335,6 +338,24 @@ private void CheckForInScenePlaced()
335338 }
336339#endif // UNITY_EDITOR
337340
341+ internal bool HasParentNetworkObject ( Transform transform )
342+ {
343+ if ( transform . parent != null )
344+ {
345+ var networkObject = transform . parent . GetComponent < NetworkObject > ( ) ;
346+ if ( networkObject != null && networkObject != this )
347+ {
348+ return true ;
349+ }
350+
351+ if ( transform . parent . parent != null )
352+ {
353+ return HasParentNetworkObject ( transform . parent ) ;
354+ }
355+ }
356+ return false ;
357+ }
358+
338359 /// <summary>
339360 /// Gets the NetworkManager that owns this NetworkObject instance
340361 /// </summary>
@@ -2295,7 +2316,7 @@ private void OnTransformParentChanged()
22952316 // we call CheckOrphanChildren() method and quickly iterate over OrphanChildren set and see if we can reparent/adopt one.
22962317 internal static HashSet < NetworkObject > OrphanChildren = new HashSet < NetworkObject > ( ) ;
22972318
2298- internal bool ApplyNetworkParenting ( bool removeParent = false , bool ignoreNotSpawned = false , bool orphanedChildPass = false )
2319+ internal bool ApplyNetworkParenting ( bool removeParent = false , bool ignoreNotSpawned = false , bool orphanedChildPass = false , bool silentParenting = false )
22992320 {
23002321 if ( ! AutoObjectParentSync )
23012322 {
@@ -2368,7 +2389,10 @@ internal bool ApplyNetworkParenting(bool removeParent = false, bool ignoreNotSpa
23682389 // to WorldPositionStays which can cause scaling issues if the parent's
23692390 // scale is not the default (Vetctor3.one) value.
23702391 transform . SetParent ( null , m_CachedWorldPositionStays ) ;
2371- InvokeBehaviourOnNetworkObjectParentChanged ( null ) ;
2392+ if ( ! silentParenting )
2393+ {
2394+ InvokeBehaviourOnNetworkObjectParentChanged ( null ) ;
2395+ }
23722396 return true ;
23732397 }
23742398
@@ -2393,7 +2417,10 @@ internal bool ApplyNetworkParenting(bool removeParent = false, bool ignoreNotSpa
23932417 }
23942418 SetCachedParent ( parentObject . transform ) ;
23952419 transform . SetParent ( parentObject . transform , m_CachedWorldPositionStays ) ;
2396- InvokeBehaviourOnNetworkObjectParentChanged ( parentObject ) ;
2420+ if ( ! silentParenting )
2421+ {
2422+ InvokeBehaviourOnNetworkObjectParentChanged ( parentObject ) ;
2423+ }
23972424 return true ;
23982425 }
23992426
@@ -3083,12 +3110,6 @@ internal SceneObject GetMessageSceneObject(ulong targetClientId = NetworkManager
30833110 var syncRotationPositionLocalSpaceRelative = obj . HasParent && ! m_CachedWorldPositionStays ;
30843111 var syncScaleLocalSpaceRelative = obj . HasParent && ! m_CachedWorldPositionStays ;
30853112
3086- // Always synchronize in-scene placed object's scale using local space
3087- if ( obj . IsSceneObject )
3088- {
3089- syncScaleLocalSpaceRelative = obj . HasParent ;
3090- }
3091-
30923113 // If auto object synchronization is turned off
30933114 if ( ! AutoObjectParentSync )
30943115 {
@@ -3165,6 +3186,16 @@ internal static NetworkObject AddSceneObject(in SceneObject sceneObject, FastBuf
31653186 // Synchronize NetworkBehaviours
31663187 var bufferSerializer = new BufferSerializer < BufferSerializerReader > ( new BufferSerializerReader ( reader ) ) ;
31673188 networkObject . SynchronizeNetworkBehaviours ( ref bufferSerializer , networkManager . LocalClientId ) ;
3189+ Debug . Log ( $ "Spawning { networkObject . name } ") ;
3190+
3191+ // If we are an in-scene placed NetworkObject and we originally had a parent but when synchronized we are
3192+ // being told we do not have a parent, then we want to clear the latest parent so it is not automatically
3193+ // "re-parented" to the original parent. This can happen if not unloading the scene and the parenting of
3194+ // the in-scene placed Networkobject changes several times over different sessions.
3195+ if ( sceneObject . IsSceneObject && ! sceneObject . HasParent && networkObject . m_LatestParent . HasValue )
3196+ {
3197+ networkObject . m_LatestParent = null ;
3198+ }
31683199
31693200 // Spawn the NetworkObject
31703201 networkManager . SpawnManager . SpawnNetworkObjectLocally ( networkObject , sceneObject , sceneObject . DestroyWithScene ) ;
0 commit comments