diff --git a/com.unity.netcode.gameobjects/CHANGELOG.md b/com.unity.netcode.gameobjects/CHANGELOG.md index f902782de2..d017ffab02 100644 --- a/com.unity.netcode.gameobjects/CHANGELOG.md +++ b/com.unity.netcode.gameobjects/CHANGELOG.md @@ -15,6 +15,7 @@ Additional documentation and release notes are available at [Multiplayer Documen ### Fixed +- Fixed `NullReferenceException` on `NetworkList` when used without a NetworkManager in scene. (#3502) - Fixed inconsistencies in the `OnSceneEvent` callback. (#3487) - Fixed issue where `NetworkClient` could persist some settings if re-using the same `NetworkManager` instance. (#3494) - Fixed issue where a pooled `NetworkObject` was not resetting the internal latest parent property when despawned. (#3494) diff --git a/com.unity.netcode.gameobjects/Runtime/Messaging/Messages/NetworkVariableDeltaMessage.cs b/com.unity.netcode.gameobjects/Runtime/Messaging/Messages/NetworkVariableDeltaMessage.cs index 7331c28e4c..728041a2f2 100644 --- a/com.unity.netcode.gameobjects/Runtime/Messaging/Messages/NetworkVariableDeltaMessage.cs +++ b/com.unity.netcode.gameobjects/Runtime/Messaging/Messages/NetworkVariableDeltaMessage.cs @@ -144,9 +144,9 @@ public void Serialize(FastBufferWriter writer, int targetVersion) var startingSize = writer.Length; var networkVariable = NetworkBehaviour.NetworkVariableFields[i]; var shouldWrite = networkVariable.IsDirty() && - networkVariable.CanClientRead(TargetClientId) && - (networkManager.IsServer || networkVariable.CanClientWrite(networkManager.LocalClientId)) && - networkVariable.CanSend(); + networkVariable.CanClientRead(TargetClientId) && + (networkManager.IsServer || networkVariable.CanWrite) && + networkVariable.CanSend(); // Prevent the server from writing to the client that owns a given NetworkVariable // Allowing the write would send an old value to the client and cause jitter diff --git a/com.unity.netcode.gameobjects/Runtime/NetworkVariable/AnticipatedNetworkVariable.cs b/com.unity.netcode.gameobjects/Runtime/NetworkVariable/AnticipatedNetworkVariable.cs index f9a92f050d..61ab721db9 100644 --- a/com.unity.netcode.gameobjects/Runtime/NetworkVariable/AnticipatedNetworkVariable.cs +++ b/com.unity.netcode.gameobjects/Runtime/NetworkVariable/AnticipatedNetworkVariable.cs @@ -213,7 +213,7 @@ public void Anticipate(T value) m_LastAnticipationCounter = m_NetworkBehaviour.NetworkManager.AnticipationSystem.AnticipationCounter; m_AnticipatedValue = value; NetworkVariableSerialization.Duplicate(m_AnticipatedValue, ref m_PreviousAnticipatedValue); - if (CanClientWrite(m_NetworkBehaviour.NetworkManager.LocalClientId)) + if (CanWrite) { AuthoritativeValue = value; } diff --git a/com.unity.netcode.gameobjects/Runtime/NetworkVariable/Collections/NetworkList.cs b/com.unity.netcode.gameobjects/Runtime/NetworkVariable/Collections/NetworkList.cs index ef8f526cc4..c53cc8fe49 100644 --- a/com.unity.netcode.gameobjects/Runtime/NetworkVariable/Collections/NetworkList.cs +++ b/com.unity.netcode.gameobjects/Runtime/NetworkVariable/Collections/NetworkList.cs @@ -428,7 +428,7 @@ public IEnumerator GetEnumerator() public void Add(T item) { // check write permissions - if (!CanClientWrite(m_NetworkBehaviour.NetworkManager.LocalClientId)) + if (CannotWrite) { LogWritePermissionError(); return; @@ -455,7 +455,7 @@ public void Add(T item) public void Clear() { // check write permissions - if (!CanClientWrite(m_NetworkBehaviour.NetworkManager.LocalClientId)) + if (CannotWrite) { LogWritePermissionError(); return; @@ -493,7 +493,7 @@ public bool Contains(T item) public bool Remove(T item) { // check write permissions - if (!CanClientWrite(m_NetworkBehaviour.NetworkManager.LocalClientId)) + if (CannotWrite) { LogWritePermissionError(); return false; @@ -542,7 +542,7 @@ public int IndexOf(T item) public void Insert(int index, T item) { // check write permissions - if (!CanClientWrite(m_NetworkBehaviour.NetworkManager.LocalClientId)) + if (CannotWrite) { LogWritePermissionError(); return; @@ -578,7 +578,7 @@ public void Insert(int index, T item) public void RemoveAt(int index) { // check write permissions - if (!CanClientWrite(m_NetworkBehaviour.NetworkManager.LocalClientId)) + if (CannotWrite) { LogWritePermissionError(); return; @@ -611,7 +611,7 @@ public T this[int index] set { // check write permissions - if (!CanClientWrite(m_NetworkBehaviour.NetworkManager.LocalClientId)) + if (CannotWrite) { LogWritePermissionError(); return; diff --git a/com.unity.netcode.gameobjects/Runtime/NetworkVariable/NetworkVariable.cs b/com.unity.netcode.gameobjects/Runtime/NetworkVariable/NetworkVariable.cs index cb5fe9e2b3..98caca807c 100644 --- a/com.unity.netcode.gameobjects/Runtime/NetworkVariable/NetworkVariable.cs +++ b/com.unity.netcode.gameobjects/Runtime/NetworkVariable/NetworkVariable.cs @@ -128,7 +128,7 @@ public virtual T Value get => m_InternalValue; set { - if (m_NetworkManager && !CanClientWrite(m_NetworkManager.LocalClientId)) + if (CannotWrite) { LogWritePermissionError(); return; @@ -162,7 +162,7 @@ public bool CheckDirtyState(bool forceCheck = false) var isDirty = base.IsDirty(); // A client without permissions invoking this method should only check to assure the current value is equal to the last known current value - if (m_NetworkManager && !CanClientWrite(m_NetworkManager.LocalClientId)) + if (CannotWrite) { // If modifications are detected, then revert back to the last known current value if (!NetworkVariableSerialization.AreEqual(ref m_InternalValue, ref m_InternalOriginalValue)) @@ -242,7 +242,7 @@ public override bool IsDirty() { // 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 // to the original collection value prior to applying updates (primarily for collections). - if (!NetworkUpdaterCheck && m_NetworkManager && !CanClientWrite(m_NetworkManager.LocalClientId) && !NetworkVariableSerialization.AreEqual(ref m_InternalValue, ref m_InternalOriginalValue)) + if (!NetworkUpdaterCheck && CannotWrite && !NetworkVariableSerialization.AreEqual(ref m_InternalValue, ref m_InternalOriginalValue)) { NetworkVariableSerialization.Duplicate(m_InternalOriginalValue, ref m_InternalValue); return true; @@ -318,7 +318,7 @@ public override void ReadDelta(FastBufferReader reader, bool keepDirtyDelta) { // 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 // to the original collection value prior to applying updates (primarily for collections). - if (m_NetworkManager && !CanClientWrite(m_NetworkManager.LocalClientId) && !NetworkVariableSerialization.AreEqual(ref m_InternalOriginalValue, ref m_InternalValue)) + if (CannotWrite && !NetworkVariableSerialization.AreEqual(ref m_InternalOriginalValue, ref m_InternalValue)) { NetworkVariableSerialization.Duplicate(m_InternalOriginalValue, ref m_InternalValue); } @@ -359,7 +359,7 @@ public override void ReadField(FastBufferReader reader) { // 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 // to the original collection value prior to applying updates (primarily for collections). - if (m_NetworkManager && !CanClientWrite(m_NetworkManager.LocalClientId) && !NetworkVariableSerialization.AreEqual(ref m_InternalOriginalValue, ref m_InternalValue)) + if (CannotWrite && !NetworkVariableSerialization.AreEqual(ref m_InternalOriginalValue, ref m_InternalValue)) { NetworkVariableSerialization.Duplicate(m_InternalOriginalValue, ref m_InternalValue); } diff --git a/com.unity.netcode.gameobjects/Runtime/NetworkVariable/NetworkVariableBase.cs b/com.unity.netcode.gameobjects/Runtime/NetworkVariable/NetworkVariableBase.cs index 8b86d356ad..a843014601 100644 --- a/com.unity.netcode.gameobjects/Runtime/NetworkVariable/NetworkVariableBase.cs +++ b/com.unity.netcode.gameobjects/Runtime/NetworkVariable/NetworkVariableBase.cs @@ -353,6 +353,16 @@ public bool CanClientWrite(ulong clientId) } } + /// + /// Returns true if the current can write to this variable; otherwise false. + /// + internal bool CanWrite => m_NetworkManager && CanClientWrite(m_NetworkManager.LocalClientId); + + /// + /// Returns false if the current can write to this variable; otherwise true. + /// + internal bool CannotWrite => m_NetworkManager && !CanClientWrite(m_NetworkManager.LocalClientId); + /// /// Returns the ClientId of the owning client ///