@@ -57,7 +57,7 @@ public override void OnInitialize()
57
57
base . OnInitialize ( ) ;
58
58
59
59
m_HasPreviousValue = true ;
60
- NetworkVariableSerialization < T > . Duplicate ( m_InternalValue , ref m_InternalOriginalValue ) ;
60
+ NetworkVariableSerialization < T > . Duplicate ( m_InternalValue , ref m_LastInternalValue ) ;
61
61
NetworkVariableSerialization < T > . Duplicate ( m_InternalValue , ref m_PreviousValue ) ;
62
62
}
63
63
@@ -73,7 +73,7 @@ public NetworkVariable(T value = default,
73
73
: base ( readPerm , writePerm )
74
74
{
75
75
m_InternalValue = value ;
76
- m_InternalOriginalValue = default ;
76
+ m_LastInternalValue = default ;
77
77
// Since we start with IsDirty = true, this doesn't need to be duplicated
78
78
// right away. It won't get read until after ResetDirty() is called, and
79
79
// the duplicate will be made there. Avoiding calling
@@ -92,25 +92,45 @@ public void Reset(T value = default)
92
92
if ( m_NetworkBehaviour == null || m_NetworkBehaviour != null && ! m_NetworkBehaviour . NetworkObject . IsSpawned )
93
93
{
94
94
m_InternalValue = value ;
95
- NetworkVariableSerialization < T > . Duplicate ( m_InternalValue , ref m_InternalOriginalValue ) ;
95
+ NetworkVariableSerialization < T > . Duplicate ( m_InternalValue , ref m_LastInternalValue ) ;
96
96
m_PreviousValue = default ;
97
97
}
98
98
}
99
99
100
100
/// <summary>
101
- /// The internal value of the NetworkVariable
101
+ /// The current internal value of the NetworkVariable.
102
102
/// </summary>
103
+ /// <remarks>
104
+ /// When using collections, this InternalValue can be updated directly without going through the <see cref="NetworkVariable{T}.Value"/> setter.
105
+ /// </remarks>
103
106
[ SerializeField ]
104
107
private protected T m_InternalValue ;
105
108
106
- // The introduction of standard .NET collections caused an issue with permissions since there is no way to detect changes in the
107
- // collection without doing a full comparison. While this approach does consume more memory per collection instance, it is the
108
- // lowest risk approach to resolving the issue where a client with no write permissions could make changes to a collection locally
109
- // which can cause a myriad of issues.
110
- private protected T m_InternalOriginalValue ;
109
+ /// <summary>
110
+ /// The last valid/authorized value of the network variable.
111
+ /// </summary>
112
+ /// <remarks>
113
+ /// The introduction of standard .NET collections caused an issue with permissions since there is no way to detect changes in the
114
+ /// collection without doing a full comparison. While this approach does consume more memory per collection instance, it is the
115
+ /// lowest risk approach to resolving the issue where a client with no write permissions could make changes to a collection locally
116
+ /// which can cause a myriad of issues.
117
+ /// </remarks>
118
+ private protected T m_LastInternalValue ;
111
119
120
+ /// <summary>
121
+ /// The most recent value that was synchronized over the network.
122
+ /// Synchronized over the network at the end of the frame in which the <see cref="NetworkVariable{T}"/> was marked dirty.
123
+ /// </summary>
124
+ /// <remarks>
125
+ /// Only contains the value synchronized over the network at the end of the last frame.
126
+ /// All in-between changes on the authority are tracked by <see cref="m_LastInternalValue"/>.
127
+ /// </remarks>
112
128
private protected T m_PreviousValue ;
113
129
130
+ /// <summary>
131
+ /// Whether this network variable has had changes synchronized over the network.
132
+ /// Indicates whether <see cref="m_PreviousValue"/> is populated and valid.
133
+ /// </summary>
114
134
private bool m_HasPreviousValue ;
115
135
private bool m_IsDisposed ;
116
136
@@ -139,7 +159,7 @@ public virtual T Value
139
159
{
140
160
T previousValue = m_InternalValue ;
141
161
m_InternalValue = value ;
142
- NetworkVariableSerialization < T > . Duplicate ( m_InternalValue , ref m_InternalOriginalValue ) ;
162
+ NetworkVariableSerialization < T > . Duplicate ( m_InternalValue , ref m_LastInternalValue ) ;
143
163
SetDirty ( true ) ;
144
164
m_IsDisposed = false ;
145
165
OnValueChanged ? . Invoke ( previousValue , m_InternalValue ) ;
@@ -165,20 +185,21 @@ public bool CheckDirtyState(bool forceCheck = false)
165
185
if ( CannotWrite )
166
186
{
167
187
// If modifications are detected, then revert back to the last known current value
168
- if ( ! NetworkVariableSerialization < T > . AreEqual ( ref m_InternalValue , ref m_InternalOriginalValue ) )
188
+ if ( ! NetworkVariableSerialization < T > . AreEqual ( ref m_InternalValue , ref m_LastInternalValue ) )
169
189
{
170
- NetworkVariableSerialization < T > . Duplicate ( m_InternalOriginalValue , ref m_InternalValue ) ;
190
+ NetworkVariableSerialization < T > . Duplicate ( m_LastInternalValue , ref m_InternalValue ) ;
171
191
}
172
192
return false ;
173
193
}
174
194
175
- // Compare the previous with the current if not dirty or forcing a check.
176
- if ( ( ! isDirty || forceCheck ) && ! NetworkVariableSerialization < T > . AreEqual ( ref m_PreviousValue , ref m_InternalValue ) )
195
+ // Compare the last internal value with the current value if not dirty or forcing a check.
196
+ if ( ( ! isDirty || forceCheck ) && ! NetworkVariableSerialization < T > . AreEqual ( ref m_LastInternalValue , ref m_InternalValue ) )
177
197
{
178
198
SetDirty ( true ) ;
179
- OnValueChanged ? . Invoke ( m_PreviousValue , m_InternalValue ) ;
199
+ OnValueChanged ? . Invoke ( m_LastInternalValue , m_InternalValue ) ;
180
200
m_IsDisposed = false ;
181
201
isDirty = true ;
202
+ NetworkVariableSerialization < T > . Duplicate ( m_InternalValue , ref m_LastInternalValue ) ;
182
203
}
183
204
return isDirty ;
184
205
}
@@ -212,11 +233,11 @@ public override void Dispose()
212
233
m_InternalValue = default ;
213
234
214
235
// Dispose the internal original value
215
- if ( m_InternalOriginalValue is IDisposable internalOriginalValueDisposable )
236
+ if ( m_LastInternalValue is IDisposable internalOriginalValueDisposable )
216
237
{
217
238
internalOriginalValueDisposable . Dispose ( ) ;
218
239
}
219
- m_InternalOriginalValue = default ;
240
+ m_LastInternalValue = default ;
220
241
221
242
// Dispose the previous value if there is one
222
243
if ( m_HasPreviousValue && m_PreviousValue is IDisposable previousValueDisposable )
@@ -245,9 +266,9 @@ public override bool IsDirty()
245
266
{
246
267
// If the client does not have write permissions but the internal value is determined to be locally modified and we are applying updates, then we should revert
247
268
// to the original collection value prior to applying updates (primarily for collections).
248
- if ( ! NetworkUpdaterCheck && CannotWrite && ! NetworkVariableSerialization < T > . AreEqual ( ref m_InternalValue , ref m_InternalOriginalValue ) )
269
+ if ( ! NetworkUpdaterCheck && CannotWrite && ! NetworkVariableSerialization < T > . AreEqual ( ref m_InternalValue , ref m_LastInternalValue ) )
249
270
{
250
- NetworkVariableSerialization < T > . Duplicate ( m_InternalOriginalValue , ref m_InternalValue ) ;
271
+ NetworkVariableSerialization < T > . Duplicate ( m_LastInternalValue , ref m_InternalValue ) ;
251
272
return true ;
252
273
}
253
274
// For most cases we can use the dirty flag.
@@ -284,7 +305,7 @@ public override void ResetDirty()
284
305
m_HasPreviousValue = true ;
285
306
NetworkVariableSerialization < T > . Duplicate ( m_InternalValue , ref m_PreviousValue ) ;
286
307
// Once updated, assure the original current value is updated for future comparison purposes
287
- NetworkVariableSerialization < T > . Duplicate ( m_InternalValue , ref m_InternalOriginalValue ) ;
308
+ NetworkVariableSerialization < T > . Duplicate ( m_InternalValue , ref m_LastInternalValue ) ;
288
309
}
289
310
base . ResetDirty ( ) ;
290
311
}
@@ -307,9 +328,9 @@ public override void ReadDelta(FastBufferReader reader, bool keepDirtyDelta)
307
328
{
308
329
// If the client does not have write permissions but the internal value is determined to be locally modified and we are applying updates, then we should revert
309
330
// to the original collection value prior to applying updates (primarily for collections).
310
- if ( CannotWrite && ! NetworkVariableSerialization < T > . AreEqual ( ref m_InternalOriginalValue , ref m_InternalValue ) )
331
+ if ( CannotWrite && ! NetworkVariableSerialization < T > . AreEqual ( ref m_LastInternalValue , ref m_InternalValue ) )
311
332
{
312
- NetworkVariableSerialization < T > . Duplicate ( m_InternalOriginalValue , ref m_InternalValue ) ;
333
+ NetworkVariableSerialization < T > . Duplicate ( m_LastInternalValue , ref m_InternalValue ) ;
313
334
}
314
335
315
336
NetworkVariableSerialization < T > . ReadDelta ( reader , ref m_InternalValue ) ;
@@ -341,17 +362,17 @@ internal override void PostDeltaRead()
341
362
m_HasPreviousValue = true ;
342
363
NetworkVariableSerialization < T > . Duplicate ( m_InternalValue , ref m_PreviousValue ) ;
343
364
// Once updated, assure the original current value is updated for future comparison purposes
344
- NetworkVariableSerialization < T > . Duplicate ( m_InternalValue , ref m_InternalOriginalValue ) ;
365
+ NetworkVariableSerialization < T > . Duplicate ( m_InternalValue , ref m_LastInternalValue ) ;
345
366
}
346
367
347
368
/// <inheritdoc />
348
369
public override void ReadField ( FastBufferReader reader )
349
370
{
350
371
// If the client does not have write permissions but the internal value is determined to be locally modified and we are applying updates, then we should revert
351
372
// to the original collection value prior to applying updates (primarily for collections).
352
- if ( CannotWrite && ! NetworkVariableSerialization < T > . AreEqual ( ref m_InternalOriginalValue , ref m_InternalValue ) )
373
+ if ( CannotWrite && ! NetworkVariableSerialization < T > . AreEqual ( ref m_LastInternalValue , ref m_InternalValue ) )
353
374
{
354
- NetworkVariableSerialization < T > . Duplicate ( m_InternalOriginalValue , ref m_InternalValue ) ;
375
+ NetworkVariableSerialization < T > . Duplicate ( m_LastInternalValue , ref m_InternalValue ) ;
355
376
}
356
377
357
378
NetworkVariableSerialization < T > . Read ( reader , ref m_InternalValue ) ;
@@ -363,7 +384,7 @@ public override void ReadField(FastBufferReader reader)
363
384
NetworkVariableSerialization < T > . Duplicate ( m_InternalValue , ref m_PreviousValue ) ;
364
385
365
386
// Once updated, assure the original current value is updated for future comparison purposes
366
- NetworkVariableSerialization < T > . Duplicate ( m_InternalValue , ref m_InternalOriginalValue ) ;
387
+ NetworkVariableSerialization < T > . Duplicate ( m_InternalValue , ref m_LastInternalValue ) ;
367
388
}
368
389
369
390
/// <inheritdoc />
0 commit comments