@@ -370,17 +370,38 @@ private void CheckForInScenePlaced()
370370 [ SerializeField ]
371371 internal bool HadBridge ;
372372#if UNITY_EDITOR
373+ private void OnApplicationUpdate ( )
374+ {
375+ NetworkObjectBridge = gameObject . AddComponent < NetworkObjectBridge > ( ) ;
376+ HadBridge = true ;
377+ // Transform synchronization is handled by unified netcode
378+ SynchronizeTransform = false ;
379+
380+ EditorApplication . update -= OnApplicationUpdate ;
381+ }
382+
373383 internal void UnifiedValidation ( )
374384 {
375385 NetworkObjectBridge = GetComponent < NetworkObjectBridge > ( ) ;
376386 GhostAdapter = GetComponent < GhostAdapter > ( ) ;
387+
377388 HasGhost = GhostAdapter != null ;
378- if ( HasGhost && NetworkObjectBridge == null )
389+ if ( HasGhost )
379390 {
380- NetworkObjectBridge = gameObject . AddComponent < NetworkObjectBridge > ( ) ;
381- HadBridge = true ;
382- // Transform synchronization is handled by unified netcode
383- SynchronizeTransform = false ;
391+ //TODO: Needs to be validated once develop-2.0.0 is merged.
392+ if ( InScenePlaced )
393+ {
394+ Debug . LogError ( $ "This experimental version of NGO does not support hybrid in-scene placed objects.") ;
395+ Destroy ( GhostAdapter ) ;
396+ HasGhost = false ;
397+ return ;
398+ }
399+
400+ if ( NetworkObjectBridge == null )
401+ {
402+ EditorApplication . update -= OnApplicationUpdate ;
403+ EditorApplication . update += OnApplicationUpdate ;
404+ }
384405 }
385406 else if ( HadBridge && ! HasGhost && ! NetworkObjectBridge )
386407 {
@@ -389,6 +410,14 @@ internal void UnifiedValidation()
389410 }
390411 }
391412#endif
413+
414+ public void ApplyScale ( Vector3 scale )
415+ {
416+ if ( HasGhost )
417+ {
418+ GhostAdapter . ApplyPostTransformMatrixScale ( scale ) ;
419+ }
420+ }
392421#endif
393422 /// <summary>
394423 /// Gets the NetworkManager that owns this NetworkObject instance
@@ -2856,33 +2885,53 @@ internal bool InitializeChildNetworkBehaviours()
28562885#endif
28572886 }
28582887#if UNIFIED_NETCODE
2859- // For now, cycle through all known NetworkTransform and NetworkRigidbodyBase derived components
2888+ // For now, cycle through all known NetworkRigidbodyBase derived components
28602889 // and destroy them all if this is a hybrid prefab instance.
28612890 // This allows a user to not have to make direct adjustments until trying out their NGO prefab
2862- // as a hybrid spawned prefab (optional to completely remove, will eventually become obsolete and
2863- // automatically removed later).
2891+ // as a hybrid spawned prefab.
28642892 if ( HasGhost && ! NetworkManager . DistributedAuthorityMode )
28652893 {
2894+ #if COM_UNITY_MODULES_PHYSICS || COM_UNITY_MODULES_PHYSICS2D
2895+ // TODO-UNIFIED: This needs to be updated to make it "opt-in".
2896+ // If the GhostAdapter is not configured for prediction but is still using a Rigidbody, then go ahead and remove it on
2897+ // the client side to improve performance by default.
2898+ // TODO-UNIFIED: Determine if recent unified physics updates does not require checking for prediction.
28662899 if ( NetworkRigidbodies != null )
28672900 {
2901+ var isServer = NetworkManager . IsServer ;
28682902 for ( int i = NetworkRigidbodies . Count - 1 ; i >= 0 ; i -- )
28692903 {
2870- // TODO-UNIFIED: This needs to be updated to make it "opt-in".
2871- // Only clients remove the rigidbody for performance purposes when running a hybrid spawn client-server topology.
2872- if ( ! NetworkManager . IsServer )
2904+ var currenObject = NetworkRigidbodies [ i ] . gameObject ;
2905+ var currentHasGhostRigidBody = currenObject . GetComponent < GhostRigidbody > ( ) != null ;
2906+ if ( ! isServer )
28732907 {
2874- var rigidBody = NetworkRigidbodies [ i ] . gameObject . GetComponent < Rigidbody > ( ) ;
2875- if ( rigidBody != null )
2908+ #if COM_UNITY_MODULES_PHYSICS
2909+ var rigidBody = currenObject . GetComponent < Rigidbody > ( ) ;
2910+
2911+ if ( rigidBody != null && ! currentHasGhostRigidBody )
28762912 {
28772913 Destroy ( rigidBody ) ;
28782914 }
2915+ #endif
2916+ #if COM_UNITY_MODULES_PHYSICS2D
2917+ var rigidBody2D = currenObject . GetComponent < Rigidbody2D > ( ) ;
2918+ if ( rigidBody2D != null && ! currentHasGhostRigidBody )
2919+ {
2920+ Destroy ( rigidBody2D ) ;
2921+ }
2922+ #endif
28792923 }
2880- ChildNetworkBehaviours . Remove ( NetworkRigidbodies [ i ] . NetworkBehaviourId ) ;
2881- Destroy ( NetworkRigidbodies [ i ] ) ;
2924+ // Both the server and clients will still remove and destroy the NetworkRigidbody
2925+ // since there is no point in synchronizing these when it is handled via unified.
2926+ var networkRigidbody = NetworkRigidbodies [ i ] ;
2927+ NetworkRigidbodies . Remove ( networkRigidbody ) ;
2928+ ChildNetworkBehaviours . Remove ( networkRigidbody . NetworkBehaviourId ) ;
2929+ Destroy ( networkRigidbody ) ;
28822930 }
2883- NetworkRigidbodies . Clear ( ) ;
28842931 }
2885-
2932+ #endif
2933+ // This is defined out since users might have derived NetworkTransforms
2934+ #if UNIFIED_NETCODE_DESTROY
28862935 // When hybrid spawning, the transform is synchronized by the GhostObject.
28872936 // As a convenience, we remove and destroy all NetworkTransforms.
28882937 // TODO-Parenting-Related-Area: We need to replicate this functionality in a GhostAdapter
@@ -2898,6 +2947,7 @@ internal bool InitializeChildNetworkBehaviours()
28982947 }
28992948 NetworkTransforms . Clear ( ) ;
29002949 }
2950+ #endif
29012951 }
29022952#endif
29032953 return true ;
0 commit comments