@@ -57,7 +57,7 @@ public override void OnInitialize()
5757 base . OnInitialize ( ) ;
5858
5959 m_HasPreviousValue = true ;
60- NetworkVariableSerialization < T > . Duplicate ( m_InternalValue , ref m_InternalOriginalValue ) ;
60+ NetworkVariableSerialization < T > . Duplicate ( m_InternalValue , ref m_LastInternalValue ) ;
6161 NetworkVariableSerialization < T > . Duplicate ( m_InternalValue , ref m_PreviousValue ) ;
6262 }
6363
@@ -73,7 +73,7 @@ public NetworkVariable(T value = default,
7373 : base ( readPerm , writePerm )
7474 {
7575 m_InternalValue = value ;
76- m_InternalOriginalValue = default ;
76+ m_LastInternalValue = default ;
7777 // Since we start with IsDirty = true, this doesn't need to be duplicated
7878 // right away. It won't get read until after ResetDirty() is called, and
7979 // the duplicate will be made there. Avoiding calling
@@ -92,25 +92,45 @@ public void Reset(T value = default)
9292 if ( m_NetworkBehaviour == null || m_NetworkBehaviour != null && ! m_NetworkBehaviour . NetworkObject . IsSpawned )
9393 {
9494 m_InternalValue = value ;
95- NetworkVariableSerialization < T > . Duplicate ( m_InternalValue , ref m_InternalOriginalValue ) ;
95+ NetworkVariableSerialization < T > . Duplicate ( m_InternalValue , ref m_LastInternalValue ) ;
9696 m_PreviousValue = default ;
9797 }
9898 }
9999
100100 /// <summary>
101- /// The internal value of the NetworkVariable
101+ /// The current internal value of the NetworkVariable.
102102 /// </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>
103106 [ SerializeField ]
104107 private protected T m_InternalValue ;
105108
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 ;
111119
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>
112128 private protected T m_PreviousValue ;
113129
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>
114134 private bool m_HasPreviousValue ;
115135 private bool m_IsDisposed ;
116136
@@ -139,7 +159,7 @@ public virtual T Value
139159 {
140160 T previousValue = m_InternalValue ;
141161 m_InternalValue = value ;
142- NetworkVariableSerialization < T > . Duplicate ( m_InternalValue , ref m_InternalOriginalValue ) ;
162+ NetworkVariableSerialization < T > . Duplicate ( m_InternalValue , ref m_LastInternalValue ) ;
143163 SetDirty ( true ) ;
144164 m_IsDisposed = false ;
145165 OnValueChanged ? . Invoke ( previousValue , m_InternalValue ) ;
@@ -165,20 +185,21 @@ public bool CheckDirtyState(bool forceCheck = false)
165185 if ( CannotWrite )
166186 {
167187 // 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 ) )
169189 {
170- NetworkVariableSerialization < T > . Duplicate ( m_InternalOriginalValue , ref m_InternalValue ) ;
190+ NetworkVariableSerialization < T > . Duplicate ( m_LastInternalValue , ref m_InternalValue ) ;
171191 }
172192 return false ;
173193 }
174194
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 ) )
177197 {
178198 SetDirty ( true ) ;
179- OnValueChanged ? . Invoke ( m_PreviousValue , m_InternalValue ) ;
199+ OnValueChanged ? . Invoke ( m_LastInternalValue , m_InternalValue ) ;
180200 m_IsDisposed = false ;
181201 isDirty = true ;
202+ NetworkVariableSerialization < T > . Duplicate ( m_InternalValue , ref m_LastInternalValue ) ;
182203 }
183204 return isDirty ;
184205 }
@@ -212,11 +233,11 @@ public override void Dispose()
212233 m_InternalValue = default ;
213234
214235 // Dispose the internal original value
215- if ( m_InternalOriginalValue is IDisposable internalOriginalValueDisposable )
236+ if ( m_LastInternalValue is IDisposable internalOriginalValueDisposable )
216237 {
217238 internalOriginalValueDisposable . Dispose ( ) ;
218239 }
219- m_InternalOriginalValue = default ;
240+ m_LastInternalValue = default ;
220241
221242 // Dispose the previous value if there is one
222243 if ( m_HasPreviousValue && m_PreviousValue is IDisposable previousValueDisposable )
@@ -245,9 +266,9 @@ public override bool IsDirty()
245266 {
246267 // 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
247268 // 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 ) )
249270 {
250- NetworkVariableSerialization < T > . Duplicate ( m_InternalOriginalValue , ref m_InternalValue ) ;
271+ NetworkVariableSerialization < T > . Duplicate ( m_LastInternalValue , ref m_InternalValue ) ;
251272 return true ;
252273 }
253274 // For most cases we can use the dirty flag.
@@ -284,7 +305,7 @@ public override void ResetDirty()
284305 m_HasPreviousValue = true ;
285306 NetworkVariableSerialization < T > . Duplicate ( m_InternalValue , ref m_PreviousValue ) ;
286307 // 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 ) ;
288309 }
289310 base . ResetDirty ( ) ;
290311 }
@@ -307,9 +328,9 @@ public override void ReadDelta(FastBufferReader reader, bool keepDirtyDelta)
307328 {
308329 // 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
309330 // 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 ) )
311332 {
312- NetworkVariableSerialization < T > . Duplicate ( m_InternalOriginalValue , ref m_InternalValue ) ;
333+ NetworkVariableSerialization < T > . Duplicate ( m_LastInternalValue , ref m_InternalValue ) ;
313334 }
314335
315336 NetworkVariableSerialization < T > . ReadDelta ( reader , ref m_InternalValue ) ;
@@ -341,17 +362,17 @@ internal override void PostDeltaRead()
341362 m_HasPreviousValue = true ;
342363 NetworkVariableSerialization < T > . Duplicate ( m_InternalValue , ref m_PreviousValue ) ;
343364 // 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 ) ;
345366 }
346367
347368 /// <inheritdoc />
348369 public override void ReadField ( FastBufferReader reader )
349370 {
350371 // 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
351372 // 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 ) )
353374 {
354- NetworkVariableSerialization < T > . Duplicate ( m_InternalOriginalValue , ref m_InternalValue ) ;
375+ NetworkVariableSerialization < T > . Duplicate ( m_LastInternalValue , ref m_InternalValue ) ;
355376 }
356377
357378 NetworkVariableSerialization < T > . Read ( reader , ref m_InternalValue ) ;
@@ -363,7 +384,7 @@ public override void ReadField(FastBufferReader reader)
363384 NetworkVariableSerialization < T > . Duplicate ( m_InternalValue , ref m_PreviousValue ) ;
364385
365386 // 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 ) ;
367388 }
368389
369390 /// <inheritdoc />
0 commit comments