@@ -74,6 +74,11 @@ internal enum __RpcExecStage
74
74
internal FastBufferWriter __beginSendServerRpc ( uint rpcMethodId , ServerRpcParams serverRpcParams , RpcDelivery rpcDelivery )
75
75
#pragma warning restore IDE1006 // restore naming rule violation check
76
76
{
77
+ if ( m_NetworkObject == null && ! IsSpawned )
78
+ {
79
+ throw new RpcException ( "The NetworkBehaviour must be spawned before calling this method." ) ;
80
+ }
81
+
77
82
return new FastBufferWriter ( k_RpcMessageDefaultSize , Allocator . Temp , k_RpcMessageMaximumSize ) ;
78
83
}
79
84
@@ -142,7 +147,7 @@ internal void __endSendServerRpc(ref FastBufferWriter bufferWriter, uint rpcMeth
142
147
{
143
148
NetworkManager . NetworkMetrics . TrackRpcSent (
144
149
NetworkManager . ServerClientId ,
145
- NetworkObject ,
150
+ m_NetworkObject ,
146
151
rpcMethodName ,
147
152
__getTypeName ( ) ,
148
153
rpcWriteSize ) ;
@@ -155,6 +160,11 @@ internal void __endSendServerRpc(ref FastBufferWriter bufferWriter, uint rpcMeth
155
160
internal FastBufferWriter __beginSendClientRpc ( uint rpcMethodId , ClientRpcParams clientRpcParams , RpcDelivery rpcDelivery )
156
161
#pragma warning restore IDE1006 // restore naming rule violation check
157
162
{
163
+ if ( m_NetworkObject == null && ! IsSpawned )
164
+ {
165
+ throw new RpcException ( "The NetworkBehaviour must be spawned before calling this method." ) ;
166
+ }
167
+
158
168
return new FastBufferWriter ( k_RpcMessageDefaultSize , Allocator . Temp , k_RpcMessageMaximumSize ) ;
159
169
}
160
170
@@ -206,7 +216,7 @@ internal void __endSendClientRpc(ref FastBufferWriter bufferWriter, uint rpcMeth
206
216
continue ;
207
217
}
208
218
// Check to make sure we are sending to only observers, if not log an error.
209
- if ( networkManager . LogLevel >= LogLevel . Error && ! NetworkObject . Observers . Contains ( targetClientId ) )
219
+ if ( networkManager . LogLevel >= LogLevel . Error && ! m_NetworkObject . Observers . Contains ( targetClientId ) )
210
220
{
211
221
NetworkLog . LogError ( GenerateObserverErrorMessage ( clientRpcParams , targetClientId ) ) ;
212
222
}
@@ -223,7 +233,7 @@ internal void __endSendClientRpc(ref FastBufferWriter bufferWriter, uint rpcMeth
223
233
continue ;
224
234
}
225
235
// Check to make sure we are sending to only observers, if not log an error.
226
- if ( networkManager . LogLevel >= LogLevel . Error && ! NetworkObject . Observers . Contains ( targetClientId ) )
236
+ if ( networkManager . LogLevel >= LogLevel . Error && ! m_NetworkObject . Observers . Contains ( targetClientId ) )
227
237
{
228
238
NetworkLog . LogError ( GenerateObserverErrorMessage ( clientRpcParams , targetClientId ) ) ;
229
239
}
@@ -232,7 +242,7 @@ internal void __endSendClientRpc(ref FastBufferWriter bufferWriter, uint rpcMeth
232
242
}
233
243
else
234
244
{
235
- var observerEnumerator = NetworkObject . Observers . GetEnumerator ( ) ;
245
+ var observerEnumerator = m_NetworkObject . Observers . GetEnumerator ( ) ;
236
246
while ( observerEnumerator . MoveNext ( ) )
237
247
{
238
248
// Skip over the host
@@ -274,7 +284,7 @@ internal void __endSendClientRpc(ref FastBufferWriter bufferWriter, uint rpcMeth
274
284
{
275
285
networkManager . NetworkMetrics . TrackRpcSent (
276
286
targetClientId ,
277
- NetworkObject ,
287
+ m_NetworkObject ,
278
288
rpcMethodName ,
279
289
__getTypeName ( ) ,
280
290
rpcWriteSize ) ;
@@ -286,20 +296,20 @@ internal void __endSendClientRpc(ref FastBufferWriter bufferWriter, uint rpcMeth
286
296
{
287
297
networkManager . NetworkMetrics . TrackRpcSent (
288
298
targetClientId ,
289
- NetworkObject ,
299
+ m_NetworkObject ,
290
300
rpcMethodName ,
291
301
__getTypeName ( ) ,
292
302
rpcWriteSize ) ;
293
303
}
294
304
}
295
305
else
296
306
{
297
- var observerEnumerator = NetworkObject . Observers . GetEnumerator ( ) ;
307
+ var observerEnumerator = m_NetworkObject . Observers . GetEnumerator ( ) ;
298
308
while ( observerEnumerator . MoveNext ( ) )
299
309
{
300
310
networkManager . NetworkMetrics . TrackRpcSent (
301
311
observerEnumerator . Current ,
302
- NetworkObject ,
312
+ m_NetworkObject ,
303
313
rpcMethodName ,
304
314
__getTypeName ( ) ,
305
315
rpcWriteSize ) ;
@@ -315,6 +325,10 @@ internal void __endSendClientRpc(ref FastBufferWriter bufferWriter, uint rpcMeth
315
325
internal FastBufferWriter __beginSendRpc ( uint rpcMethodId , RpcParams rpcParams , RpcAttribute . RpcAttributeParams attributeParams , SendTo defaultTarget , RpcDelivery rpcDelivery )
316
326
#pragma warning restore IDE1006 // restore naming rule violation check
317
327
{
328
+ if ( m_NetworkObject == null && ! IsSpawned )
329
+ {
330
+ throw new RpcException ( "The NetworkBehaviour must be spawned before calling this method." ) ;
331
+ }
318
332
if ( attributeParams . RequireOwnership && ! IsOwner )
319
333
{
320
334
throw new RpcException ( "This RPC can only be sent by its owner." ) ;
@@ -546,6 +560,11 @@ internal bool IsBehaviourEditable()
546
560
( ( networkManager . DistributedAuthorityMode && m_NetworkObject . IsOwner ) || ( ! networkManager . DistributedAuthorityMode && networkManager . IsServer ) ) ;
547
561
}
548
562
563
+ internal void SetNetworkObject ( NetworkObject networkObject )
564
+ {
565
+ m_NetworkObject = networkObject ;
566
+ }
567
+
549
568
// TODO: this needs an overhaul. It's expensive, it's ja little naive in how it looks for networkObject in
550
569
// its parent and worst, it creates a puzzle if you are a NetworkBehaviour wanting to see if you're live or not
551
570
// (e.g. editor code). All you want to do is find out if NetworkManager is null, but to do that you
@@ -635,43 +654,32 @@ protected NetworkBehaviour GetNetworkBehaviour(ushort behaviourId)
635
654
/// </summary>
636
655
internal void UpdateNetworkProperties ( )
637
656
{
638
- var networkObject = NetworkObject ;
639
- // Set NetworkObject dependent properties
640
- if ( networkObject != null )
641
- {
642
- var networkManager = NetworkManager ;
643
- // Set identification related properties
644
- NetworkObjectId = networkObject . NetworkObjectId ;
645
- IsLocalPlayer = networkObject . IsLocalPlayer ;
646
-
647
- // This is "OK" because GetNetworkBehaviourOrderIndex uses the order of
648
- // NetworkObject.ChildNetworkBehaviours which is set once when first
649
- // accessed.
650
- NetworkBehaviourId = networkObject . GetNetworkBehaviourOrderIndex ( this ) ;
651
-
652
- // Set ownership related properties
653
- IsOwnedByServer = networkObject . IsOwnedByServer ;
654
- IsOwner = networkObject . IsOwner ;
655
- OwnerClientId = networkObject . OwnerClientId ;
656
-
657
- // Set NetworkManager dependent properties
658
- if ( networkManager != null )
659
- {
660
- IsHost = networkManager . IsListening && networkManager . IsHost ;
661
- IsClient = networkManager . IsListening && networkManager . IsClient ;
662
- IsServer = networkManager . IsListening && networkManager . IsServer ;
663
- LocalClient = networkManager . LocalClient ;
664
- HasAuthority = networkObject . HasAuthority ;
665
- ServerIsHost = networkManager . IsListening && networkManager . ServerIsHost ;
666
- }
667
- }
668
- else // Shouldn't happen, but if so then set the properties to their default value;
657
+ var networkObject = m_NetworkObject ;
658
+ var networkManager = NetworkManager ;
659
+
660
+ // Set identification related properties
661
+ NetworkObjectId = networkObject . NetworkObjectId ;
662
+ IsLocalPlayer = networkObject . IsLocalPlayer ;
663
+
664
+ // This is "OK" because GetNetworkBehaviourOrderIndex uses the order of
665
+ // NetworkObject.ChildNetworkBehaviours which is set once when first
666
+ // accessed.
667
+ NetworkBehaviourId = networkObject . GetNetworkBehaviourOrderIndex ( this ) ;
668
+
669
+ // Set ownership related properties
670
+ IsOwnedByServer = networkObject . IsOwnedByServer ;
671
+ IsOwner = networkObject . IsOwner ;
672
+ OwnerClientId = networkObject . OwnerClientId ;
673
+
674
+ // Set NetworkManager dependent properties
675
+ if ( networkManager != null )
669
676
{
670
- OwnerClientId = NetworkObjectId = default ;
671
- IsOwnedByServer = IsOwner = IsHost = IsClient = IsServer = ServerIsHost = default ;
672
- NetworkBehaviourId = default ;
673
- LocalClient = default ;
674
- HasAuthority = default ;
677
+ IsHost = networkManager . IsListening && networkManager . IsHost ;
678
+ IsClient = networkManager . IsListening && networkManager . IsClient ;
679
+ IsServer = networkManager . IsListening && networkManager . IsServer ;
680
+ LocalClient = networkManager . LocalClient ;
681
+ HasAuthority = networkObject . HasAuthority ;
682
+ ServerIsHost = networkManager . IsListening && networkManager . ServerIsHost ;
675
683
}
676
684
}
677
685
@@ -752,8 +760,11 @@ public virtual void OnNetworkDespawn() { }
752
760
/// </summary>
753
761
public virtual void OnNetworkPreDespawn ( ) { }
754
762
755
- internal void NetworkPreSpawn ( ref NetworkManager networkManager )
763
+ internal void NetworkPreSpawn ( ref NetworkManager networkManager , NetworkObject networkObject )
756
764
{
765
+ m_NetworkObject = networkObject ;
766
+ UpdateNetworkProperties ( ) ;
767
+
757
768
try
758
769
{
759
770
OnNetworkPreSpawn ( ref networkManager ) ;
@@ -767,12 +778,10 @@ internal void NetworkPreSpawn(ref NetworkManager networkManager)
767
778
internal void InternalOnNetworkSpawn ( )
768
779
{
769
780
IsSpawned = true ;
781
+ // Initialize the NetworkVariables so they are accessible in OnNetworkSpawn;
770
782
InitializeVariables ( ) ;
771
783
UpdateNetworkProperties ( ) ;
772
- }
773
784
774
- internal void VisibleOnNetworkSpawn ( )
775
- {
776
785
try
777
786
{
778
787
OnNetworkSpawn ( ) ;
@@ -782,9 +791,10 @@ internal void VisibleOnNetworkSpawn()
782
791
Debug . LogException ( e ) ;
783
792
}
784
793
794
+ // Initialize again in case the user's OnNetworkSpawn changed something
785
795
InitializeVariables ( ) ;
786
796
787
- if ( NetworkObject . HasAuthority )
797
+ if ( m_NetworkObject . HasAuthority )
788
798
{
789
799
// Since we just spawned the object and since user code might have modified their NetworkVariable, esp.
790
800
// NetworkList, we need to mark the object as free of updates.
@@ -872,11 +882,10 @@ public virtual void OnGainedOwnership() { }
872
882
873
883
internal void InternalOnGainedOwnership ( )
874
884
{
875
- UpdateNetworkProperties ( ) ;
876
885
// New owners need to assure any NetworkVariables they have write permissions
877
886
// to are updated so the previous and original values are aligned with the
878
887
// current value (primarily for collections).
879
- if ( OwnerClientId == NetworkManager . LocalClientId )
888
+ if ( IsOwner )
880
889
{
881
890
UpdateNetworkVariableOnOwnershipChanged ( ) ;
882
891
}
@@ -907,12 +916,6 @@ internal void InternalOnOwnershipChanged(ulong previous, ulong current)
907
916
/// </summary>
908
917
public virtual void OnLostOwnership ( ) { }
909
918
910
- internal void InternalOnLostOwnership ( )
911
- {
912
- UpdateNetworkProperties ( ) ;
913
- OnLostOwnership ( ) ;
914
- }
915
-
916
919
/// <summary>
917
920
/// Gets called when the parent NetworkObject of this NetworkBehaviour's NetworkObject has changed.
918
921
/// </summary>
@@ -1104,7 +1107,7 @@ internal void NetworkVariableUpdate(ulong targetClientId, bool forceSend = false
1104
1107
1105
1108
// Getting these ahead of time actually improves performance
1106
1109
var networkManager = NetworkManager ;
1107
- var networkObject = NetworkObject ;
1110
+ var networkObject = m_NetworkObject ;
1108
1111
var behaviourIndex = networkObject . GetNetworkBehaviourOrderIndex ( this ) ;
1109
1112
var messageManager = networkManager . MessageManager ;
1110
1113
var connectionManager = networkManager . ConnectionManager ;
@@ -1190,7 +1193,7 @@ private bool CouldHaveDirtyNetworkVariables()
1190
1193
}
1191
1194
// If it's dirty but can't be sent yet, we have to keep monitoring it until one of the
1192
1195
// conditions blocking its send changes.
1193
- NetworkManager . BehaviourUpdater . AddForUpdate ( NetworkObject ) ;
1196
+ NetworkManager . BehaviourUpdater . AddForUpdate ( m_NetworkObject ) ;
1194
1197
}
1195
1198
}
1196
1199
@@ -1551,12 +1554,12 @@ internal virtual void InternalOnDestroy()
1551
1554
public virtual void OnDestroy ( )
1552
1555
{
1553
1556
InternalOnDestroy ( ) ;
1554
- if ( NetworkObject != null && NetworkObject . IsSpawned && IsSpawned )
1557
+ if ( m_NetworkObject != null && m_NetworkObject . IsSpawned && IsSpawned )
1555
1558
{
1556
1559
// If the associated NetworkObject is still spawned then this
1557
1560
// NetworkBehaviour will be removed from the NetworkObject's
1558
1561
// ChildNetworkBehaviours list.
1559
- NetworkObject . OnNetworkBehaviourDestroyed ( this ) ;
1562
+ m_NetworkObject . OnNetworkBehaviourDestroyed ( this ) ;
1560
1563
}
1561
1564
1562
1565
// this seems odd to do here, but in fact especially in tests we can find ourselves
@@ -1575,6 +1578,8 @@ public virtual void OnDestroy()
1575
1578
{
1576
1579
NetworkVariableFields [ i ] . Dispose ( ) ;
1577
1580
}
1581
+
1582
+ m_NetworkObject = null ;
1578
1583
}
1579
1584
}
1580
1585
}
0 commit comments