From 13abd463c7803865d0ce0d0303365959a331d1b6 Mon Sep 17 00:00:00 2001 From: NoelStephensUnity Date: Fri, 13 Jun 2025 07:35:59 -0500 Subject: [PATCH 1/4] update updating change log and package version --- com.unity.netcode.gameobjects/CHANGELOG.md | 7 +------ com.unity.netcode.gameobjects/package.json | 2 +- 2 files changed, 2 insertions(+), 7 deletions(-) diff --git a/com.unity.netcode.gameobjects/CHANGELOG.md b/com.unity.netcode.gameobjects/CHANGELOG.md index 51fe4a90f6..7d0ec33d6f 100644 --- a/com.unity.netcode.gameobjects/CHANGELOG.md +++ b/com.unity.netcode.gameobjects/CHANGELOG.md @@ -6,10 +6,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) Additional documentation and release notes are available at [Multiplayer Documentation](https://docs-multiplayer.unity3d.com). -## [Unreleased] - -### Added - +## [2.4.2] - 2025-06-13 ### Fixed @@ -18,8 +15,6 @@ Additional documentation and release notes are available at [Multiplayer Documen - Fixed issue where the initial client synchronization pre-serialization process was not excluding spawned `NetworkObject` instances that already had pending visibility for the client being synchronized. (#3488) - Fixed issue where there was a potential for a small memory leak in the `ConnectionApprovedMessage`. (#3486) -### Changed - ## [2.4.1] - 2025-06-11 diff --git a/com.unity.netcode.gameobjects/package.json b/com.unity.netcode.gameobjects/package.json index c43dc42ec2..e29f475fc6 100644 --- a/com.unity.netcode.gameobjects/package.json +++ b/com.unity.netcode.gameobjects/package.json @@ -2,7 +2,7 @@ "name": "com.unity.netcode.gameobjects", "displayName": "Netcode for GameObjects", "description": "Netcode for GameObjects is a high-level netcode SDK that provides networking capabilities to GameObject/MonoBehaviour workflows within Unity and sits on top of underlying transport layer.", - "version": "2.4.1", + "version": "2.4.2", "unity": "6000.0", "dependencies": { "com.unity.nuget.mono-cecil": "1.11.4", From 7bbc1c3a950ed4c5c10f3be25bd19ae1900d5f52 Mon Sep 17 00:00:00 2001 From: Noel Stephens Date: Fri, 13 Jun 2025 19:00:28 -0500 Subject: [PATCH 2/4] fix: Avoid throwing exception when using NetworkList without a NetworkManager [Up-port] (#3504) Up-port of #3502 Fixes #2539 ## Changelog - Added: `LocalClientCannotWrite` function to co-locate the shared functionality - Fixed: Ensure that the `NetworkManager` exists before attempting to access the `LocalClientId` ## Testing and Documentation - No tests have been added. ## Backport Backported in #3502 --------- Co-authored-by: unity-renovate[bot] <120015202+unity-renovate[bot]@users.noreply.github.com> Co-authored-by: Emma --- com.unity.netcode.gameobjects/CHANGELOG.md | 1 + .../Messages/NetworkVariableDeltaMessage.cs | 6 +++--- .../NetworkVariable/AnticipatedNetworkVariable.cs | 2 +- .../NetworkVariable/Collections/NetworkList.cs | 12 ++++++------ .../Runtime/NetworkVariable/NetworkVariable.cs | 10 +++++----- .../Runtime/NetworkVariable/NetworkVariableBase.cs | 10 ++++++++++ 6 files changed, 26 insertions(+), 15 deletions(-) diff --git a/com.unity.netcode.gameobjects/CHANGELOG.md b/com.unity.netcode.gameobjects/CHANGELOG.md index 7d0ec33d6f..937a0193b4 100644 --- a/com.unity.netcode.gameobjects/CHANGELOG.md +++ b/com.unity.netcode.gameobjects/CHANGELOG.md @@ -10,6 +10,7 @@ Additional documentation and release notes are available at [Multiplayer Documen ### Fixed +- Fixed `NullReferenceException` on `NetworkList` when used without a NetworkManager in scene. (#3503) - Fixed issue where `NetworkClient` could persist some settings if re-using the same `NetworkManager` instance. (#3491) - Fixed issue where a pooled `NetworkObject` was not resetting the internal latest parent property when despawned. (#3491) - Fixed issue where the initial client synchronization pre-serialization process was not excluding spawned `NetworkObject` instances that already had pending visibility for the client being synchronized. (#3488) diff --git a/com.unity.netcode.gameobjects/Runtime/Messaging/Messages/NetworkVariableDeltaMessage.cs b/com.unity.netcode.gameobjects/Runtime/Messaging/Messages/NetworkVariableDeltaMessage.cs index 05ae29b32e..af520a0468 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 5fe5d40818..2e14bccf9c 100644 --- a/com.unity.netcode.gameobjects/Runtime/NetworkVariable/AnticipatedNetworkVariable.cs +++ b/com.unity.netcode.gameobjects/Runtime/NetworkVariable/AnticipatedNetworkVariable.cs @@ -217,7 +217,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 97fbeabc72..1a78fc7f81 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_NetworkManager.LocalClientId)) + if (CannotWrite) { LogWritePermissionError(); return; @@ -455,7 +455,7 @@ public void Add(T item) public void Clear() { // check write permissions - if (!CanClientWrite(m_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_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_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_NetworkManager.LocalClientId)) + if (CannotWrite) { throw new InvalidOperationException("Client is not allowed to write to this NetworkList"); } @@ -610,7 +610,7 @@ public T this[int index] set { // check write permissions - if (!CanClientWrite(m_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 21f92957d2..068a6bfb68 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)) @@ -245,7 +245,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; @@ -307,7 +307,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); } @@ -349,7 +349,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 94871ab329..8761496d2a 100644 --- a/com.unity.netcode.gameobjects/Runtime/NetworkVariable/NetworkVariableBase.cs +++ b/com.unity.netcode.gameobjects/Runtime/NetworkVariable/NetworkVariableBase.cs @@ -381,6 +381,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 /// From 8cb3541e8565dc1971348489781593c2cbf0e401 Mon Sep 17 00:00:00 2001 From: NoelStephensUnity Date: Mon, 16 Jun 2025 13:48:45 -0500 Subject: [PATCH 3/4] update Adding unreleased changelog set. --- com.unity.netcode.gameobjects/CHANGELOG.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/com.unity.netcode.gameobjects/CHANGELOG.md b/com.unity.netcode.gameobjects/CHANGELOG.md index 937a0193b4..c50b82e070 100644 --- a/com.unity.netcode.gameobjects/CHANGELOG.md +++ b/com.unity.netcode.gameobjects/CHANGELOG.md @@ -6,6 +6,15 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) Additional documentation and release notes are available at [Multiplayer Documentation](https://docs-multiplayer.unity3d.com). +## [Unreleased] + +### Fixed + +### Added + +### Changed + + ## [2.4.2] - 2025-06-13 ### Fixed From 4d6c9d28607c9932d199dffa0141a97bfe3afc70 Mon Sep 17 00:00:00 2001 From: NoelStephensUnity Date: Mon, 16 Jun 2025 13:51:43 -0500 Subject: [PATCH 4/4] update Fixing merge issue with change log. --- com.unity.netcode.gameobjects/CHANGELOG.md | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/com.unity.netcode.gameobjects/CHANGELOG.md b/com.unity.netcode.gameobjects/CHANGELOG.md index 33e07d2439..2f83933764 100644 --- a/com.unity.netcode.gameobjects/CHANGELOG.md +++ b/com.unity.netcode.gameobjects/CHANGELOG.md @@ -8,9 +8,12 @@ Additional documentation and release notes are available at [Multiplayer Documen ## [Unreleased] +### Added + +- Added `NetworkPrefabInstanceHandlerWithData`, a variant of `INetworkPrefabInstanceHandler` that provides access to custom instantiation data directly within the `Instantiate()` method. (#3430) + ### Fixed -### Added ### Changed @@ -44,7 +47,7 @@ Additional documentation and release notes are available at [Multiplayer Documen - Added `SinglePlayerTransport` that provides the ability to start as a host for a single player network session. (#3473) - When using UnityTransport >=2.4 and Unity >= 6000.1.0a1, SetConnectionData will accept a fully qualified hostname instead of an IP as a connect address on the client side. (#3441) -- Added `NetworkPrefabInstanceHandlerWithData`, a variant of `INetworkPrefabInstanceHandler` that provides access to custom instantiation data directly within the `Instantiate()` method. (#3430) + ### Fixed