11using System . Collections . Generic ;
2+ using System . Runtime . CompilerServices ;
23using Unity . Profiling ;
34
45namespace Unity . Netcode
@@ -23,6 +24,115 @@ internal void AddForUpdate(NetworkObject networkObject)
2324 m_PendingDirtyNetworkObjects . Add ( networkObject ) ;
2425 }
2526
27+ [ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
28+ internal bool ProcessDirtyObjectServer ( NetworkObject dirtyObj , bool forceSend )
29+ {
30+ var sentMessages = false ;
31+ for ( int k = 0 ; k < dirtyObj . ChildNetworkBehaviours . Count ; k ++ )
32+ {
33+ dirtyObj . ChildNetworkBehaviours [ k ] . PreVariableUpdate ( ) ;
34+ }
35+
36+ for ( int i = 0 ; i < m_ConnectionManager . ConnectedClientsList . Count ; i ++ )
37+ {
38+ var client = m_ConnectionManager . ConnectedClientsList [ i ] ;
39+ if ( m_NetworkManager . DistributedAuthorityMode || dirtyObj . IsNetworkVisibleTo ( client . ClientId ) )
40+ {
41+ // Sync just the variables for just the objects this client sees
42+ for ( int k = 0 ; k < dirtyObj . ChildNetworkBehaviours . Count ; k ++ )
43+ {
44+ dirtyObj . ChildNetworkBehaviours [ k ] . NetworkVariableUpdate ( client . ClientId , forceSend ) ;
45+ sentMessages = true ;
46+ }
47+ }
48+ }
49+ return sentMessages ;
50+ }
51+
52+ [ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
53+ internal bool ProcessDirtyObjectClient ( NetworkObject dirtyObj , bool forceSend )
54+ {
55+ var sentMessages = false ;
56+ if ( dirtyObj . IsOwner )
57+ {
58+ for ( int k = 0 ; k < dirtyObj . ChildNetworkBehaviours . Count ; k ++ )
59+ {
60+ dirtyObj . ChildNetworkBehaviours [ k ] . PreVariableUpdate ( ) ;
61+ }
62+ for ( int k = 0 ; k < dirtyObj . ChildNetworkBehaviours . Count ; k ++ )
63+ {
64+ dirtyObj . ChildNetworkBehaviours [ k ] . NetworkVariableUpdate ( NetworkManager . ServerClientId , forceSend ) ;
65+ sentMessages = true ;
66+ }
67+ }
68+ return sentMessages ;
69+ }
70+
71+ [ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
72+ internal void PostProcessDirtyObject ( NetworkObject dirtyObj )
73+ {
74+ for ( int k = 0 ; k < dirtyObj . ChildNetworkBehaviours . Count ; k ++ )
75+ {
76+ var behaviour = dirtyObj . ChildNetworkBehaviours [ k ] ;
77+ for ( int i = 0 ; i < behaviour . NetworkVariableFields . Count ; i ++ )
78+ {
79+ // Set to true for NetworkVariable to ignore duplication of the
80+ // "internal original value" for collections support.
81+ behaviour . NetworkVariableFields [ i ] . NetworkUpdaterCheck = true ;
82+ if ( behaviour . NetworkVariableFields [ i ] . IsDirty ( ) &&
83+ ! behaviour . NetworkVariableIndexesToResetSet . Contains ( i ) )
84+ {
85+ behaviour . NetworkVariableIndexesToResetSet . Add ( i ) ;
86+ behaviour . NetworkVariableIndexesToReset . Add ( i ) ;
87+ }
88+ // Reset back to false when done
89+ behaviour . NetworkVariableFields [ i ] . NetworkUpdaterCheck = false ;
90+ }
91+ }
92+ }
93+
94+ [ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
95+ internal void ResetDirtyObject ( NetworkObject dirtyObj , bool forceSend )
96+ {
97+ foreach ( var behaviour in dirtyObj . ChildNetworkBehaviours )
98+ {
99+ behaviour . PostNetworkVariableWrite ( forceSend ) ;
100+ }
101+ }
102+
103+ /// <summary>
104+ /// Temporary work-around for assuring any pending dirty states are pushed out prior to showing the object
105+ /// TODO: We need to send all messages that are specific to a NetworkObject along with a NetworkObject event header
106+ /// such that messages will be processed after spawned.
107+ ///
108+ /// </summary>
109+ /// <param name="networkObject"></param>
110+ internal void ForceSendIfDirtyOnNetworkShow ( NetworkObject networkObject )
111+ {
112+ // Exit early if no pending dirty NetworkVariables.
113+ if ( ! m_PendingDirtyNetworkObjects . Contains ( networkObject ) )
114+ {
115+ return ;
116+ }
117+
118+ // Process a bit differently whether client or server
119+ if ( m_NetworkManager . IsServer )
120+ {
121+ ProcessDirtyObjectServer ( networkObject , true ) ;
122+ }
123+ else
124+ {
125+ ProcessDirtyObjectClient ( networkObject , true ) ;
126+ }
127+
128+ // Handle post processing and resetting of the NetworkObject
129+ PostProcessDirtyObject ( networkObject ) ;
130+ ResetDirtyObject ( networkObject , true ) ;
131+
132+ // Remove it from the pending dirty objects list
133+ m_PendingDirtyNetworkObjects . Remove ( networkObject ) ;
134+ }
135+
26136 /// <summary>
27137 /// Sends NetworkVariable deltas
28138 /// </summary>
@@ -49,76 +159,29 @@ internal bool NetworkBehaviourUpdate(bool forceSend = false)
49159 {
50160 foreach ( var dirtyObj in m_DirtyNetworkObjects )
51161 {
52- for ( int k = 0 ; k < dirtyObj . ChildNetworkBehaviours . Count ; k ++ )
53- {
54- dirtyObj . ChildNetworkBehaviours [ k ] . PreVariableUpdate ( ) ;
55- }
56-
57- for ( int i = 0 ; i < m_ConnectionManager . ConnectedClientsList . Count ; i ++ )
58- {
59- var client = m_ConnectionManager . ConnectedClientsList [ i ] ;
60- if ( m_NetworkManager . DistributedAuthorityMode || dirtyObj . IsNetworkVisibleTo ( client . ClientId ) )
61- {
62- // Sync just the variables for just the objects this client sees
63- for ( int k = 0 ; k < dirtyObj . ChildNetworkBehaviours . Count ; k ++ )
64- {
65- dirtyObj . ChildNetworkBehaviours [ k ] . NetworkVariableUpdate ( client . ClientId , forceSend ) ;
66- sentMessages = true ;
67- }
68- }
69- }
162+ sentMessages = sentMessages || ProcessDirtyObjectServer ( dirtyObj , forceSend ) ;
70163 }
71164 }
72165 else
73166 {
74167 // when client updates the server, it tells it about all its objects
75- foreach ( var sobj in m_DirtyNetworkObjects )
168+ foreach ( var dirtyObj in m_DirtyNetworkObjects )
76169 {
77- if ( sobj . IsOwner )
78- {
79- for ( int k = 0 ; k < sobj . ChildNetworkBehaviours . Count ; k ++ )
80- {
81- sobj . ChildNetworkBehaviours [ k ] . PreVariableUpdate ( ) ;
82- }
83- for ( int k = 0 ; k < sobj . ChildNetworkBehaviours . Count ; k ++ )
84- {
85- sobj . ChildNetworkBehaviours [ k ] . NetworkVariableUpdate ( NetworkManager . ServerClientId , forceSend ) ;
86- sentMessages = true ;
87- }
88- }
170+ sentMessages = sentMessages || ProcessDirtyObjectClient ( dirtyObj , forceSend ) ;
89171 }
90172 }
91173
92174 foreach ( var dirtyObj in m_DirtyNetworkObjects )
93175 {
94- for ( int k = 0 ; k < dirtyObj . ChildNetworkBehaviours . Count ; k ++ )
95- {
96- var behaviour = dirtyObj . ChildNetworkBehaviours [ k ] ;
97- for ( int i = 0 ; i < behaviour . NetworkVariableFields . Count ; i ++ )
98- {
99- // Set to true for NetworkVariable to ignore duplication of the
100- // "internal original value" for collections support.
101- behaviour . NetworkVariableFields [ i ] . NetworkUpdaterCheck = true ;
102- if ( behaviour . NetworkVariableFields [ i ] . IsDirty ( ) &&
103- ! behaviour . NetworkVariableIndexesToResetSet . Contains ( i ) )
104- {
105- behaviour . NetworkVariableIndexesToResetSet . Add ( i ) ;
106- behaviour . NetworkVariableIndexesToReset . Add ( i ) ;
107- }
108- // Reset back to false when done
109- behaviour . NetworkVariableFields [ i ] . NetworkUpdaterCheck = false ;
110- }
111- }
176+ PostProcessDirtyObject ( dirtyObj ) ;
112177 }
113178
114179 // Now, reset all the no-longer-dirty variables
115180 foreach ( var dirtyObj in m_DirtyNetworkObjects )
116181 {
117- foreach ( var behaviour in dirtyObj . ChildNetworkBehaviours )
118- {
119- behaviour . PostNetworkVariableWrite ( forceSend ) ;
120- }
182+ ResetDirtyObject ( dirtyObj , forceSend ) ;
121183 }
184+
122185 m_DirtyNetworkObjects . Clear ( ) ;
123186 }
124187 finally
0 commit comments