@@ -34,6 +34,12 @@ public abstract class NetworkVariableBase : IDisposable
34
34
private protected NetworkBehaviour m_NetworkBehaviour ;
35
35
private NetworkManager m_InternalNetworkManager ;
36
36
37
+ // Determines if this NetworkVariable has been "initialized" to prevent initializing more than once which can happen when first
38
+ // instantiated and spawned. If this NetworkVariable instance is on an in-scene placed NetworkObject =or= a pooled NetworkObject
39
+ // that can persist between sessions and/or be recycled we need to reset the LastUpdateSent value prior to spawning otherwise
40
+ // this NetworkVariableBase property instance will not update until the last session time used.
41
+ internal bool HasBeenInitialized { get ; private set ; }
42
+
37
43
public NetworkBehaviour GetBehaviour ( )
38
44
{
39
45
return m_NetworkBehaviour ;
@@ -49,37 +55,82 @@ internal void LogWritePermissionError()
49
55
Debug . LogError ( GetWritePermissionError ( ) ) ;
50
56
}
51
57
52
- private protected NetworkManager m_NetworkManager
53
- {
54
- get
55
- {
56
- if ( m_InternalNetworkManager == null && m_NetworkBehaviour && m_NetworkBehaviour . NetworkObject ? . NetworkManager )
57
- {
58
- m_InternalNetworkManager = m_NetworkBehaviour . NetworkObject ? . NetworkManager ;
59
- }
60
- return m_InternalNetworkManager ;
61
- }
62
- }
58
+ private protected NetworkManager m_NetworkManager => m_InternalNetworkManager ;
63
59
64
60
/// <summary>
65
61
/// Initializes the NetworkVariable
66
62
/// </summary>
67
63
/// <param name="networkBehaviour">The NetworkBehaviour the NetworkVariable belongs to</param>
68
64
public void Initialize ( NetworkBehaviour networkBehaviour )
69
65
{
70
- m_InternalNetworkManager = null ;
66
+ // If we have already been initialized, then exit early.
67
+ // This can happen on the very first instantiation and spawning of the associated NetworkObject
68
+ if ( HasBeenInitialized )
69
+ {
70
+ return ;
71
+ }
72
+
73
+ // Throw an exception if there is an invalid NetworkBehaviour parameter
74
+ if ( ! networkBehaviour )
75
+ {
76
+ throw new Exception ( $ "[{ GetType ( ) . Name } ][Initialize] { nameof ( NetworkBehaviour ) } parameter passed in is null!") ;
77
+ }
71
78
m_NetworkBehaviour = networkBehaviour ;
72
- if ( m_NetworkBehaviour && m_NetworkBehaviour . NetworkObject ? . NetworkManager )
79
+
80
+ // Throw an exception if there is no NetworkManager available
81
+ if ( ! m_NetworkBehaviour . NetworkManager )
73
82
{
74
- m_InternalNetworkManager = m_NetworkBehaviour . NetworkObject ? . NetworkManager ;
83
+ // Exit early if there has yet to be a NetworkManager assigned.
84
+ // This is ok because Initialize is invoked multiple times until
85
+ // it is considered "initialized".
86
+ return ;
87
+ }
75
88
76
- if ( m_NetworkBehaviour . NetworkManager . NetworkTimeSystem != null )
77
- {
78
- UpdateLastSentTime ( ) ;
79
- }
89
+ if ( ! m_NetworkBehaviour . NetworkObject )
90
+ {
91
+ // Exit early if there has yet to be a NetworkObject assigned.
92
+ // This is ok because Initialize is invoked multiple times until
93
+ // it is considered "initialized".
94
+ return ;
80
95
}
81
96
97
+ if ( ! m_NetworkBehaviour . NetworkObject . NetworkManagerOwner )
98
+ {
99
+ // Exit early if there has yet to be a NetworkManagerOwner assigned
100
+ // to the NetworkObject. This is ok because Initialize is invoked
101
+ // multiple times until it is considered "initialized".
102
+ return ;
103
+ }
104
+ m_InternalNetworkManager = m_NetworkBehaviour . NetworkObject . NetworkManagerOwner ;
105
+
82
106
OnInitialize ( ) ;
107
+
108
+ // Some unit tests don't operate with a running NetworkManager.
109
+ // Only update the last time if there is a NetworkTimeSystem.
110
+ if ( m_InternalNetworkManager . NetworkTimeSystem != null )
111
+ {
112
+ // Update our last sent time relative to when this was initialized
113
+ UpdateLastSentTime ( ) ;
114
+
115
+ // At this point, this instance is considered initialized
116
+ HasBeenInitialized = true ;
117
+ }
118
+ else if ( m_InternalNetworkManager . LogLevel == LogLevel . Developer )
119
+ {
120
+ Debug . LogWarning ( $ "[{ m_NetworkBehaviour . name } ][{ m_NetworkBehaviour . GetType ( ) . Name } ][{ GetType ( ) . Name } ][Initialize] { nameof ( NetworkManager ) } has no { nameof ( NetworkTimeSystem ) } assigned!") ;
121
+ }
122
+ }
123
+
124
+ /// <summary>
125
+ /// Deinitialize is invoked when a NetworkObject is despawned.
126
+ /// This allows for a recyled NetworkObject (in-scene or pooled)
127
+ /// to be properly initialized upon the next use/spawn.
128
+ /// </summary>
129
+ internal void Deinitialize ( )
130
+ {
131
+ // When despawned, reset the HasBeenInitialized so if the associated NetworkObject instance
132
+ // is recylced (i.e. in-scene placed or pooled) it will re-initialize the LastUpdateSent time.
133
+ HasBeenInitialized = false ;
83
134
}
84
135
85
136
/// <summary>
0 commit comments