From c78f679bdd3b3784b875dd4c41a42e9f5dee8988 Mon Sep 17 00:00:00 2001 From: Noel Stephens Date: Tue, 8 Sep 2026 11:37:12 -0500 Subject: [PATCH 1/4] chore: netcode for entities 7.0.0 as a dependency, unified api behind a define N4E becomes a hard dependency at 7.0.0, and com.unity.transport moves to 6.5.0 to match it. N4E 7.0.0 ships its unified API - GhostObject, GhostBehaviour, GhostField - behind NETCODE_GAMEOBJECT_BRIDGE_EXPERIMENTAL, which leaves those types internal in the configuration NGO ships. A public type cannot derive from an internal one, so the unified path can no longer key off the package being present: the UNIFIED_NETCODE versionDefine is removed from the four assembly definitions and the symbol is set by the project instead, alongside N4E's own define. NetworkObjectBridge is internal for the same reason, and UnifiedBootstrap raises an #error when only one of the two defines is set. With N4E present the two packages share the Unity.Netcode namespace, which breaks three things outside the unified gates: - N4E's Netcode facade type shadows the namespace, so 22 XML doc crefs and one nameof that qualified with Netcode. stopped resolving. - N4E declares an INetworkStreamDriverConstructor in the shared root that the enclosing namespace finds ahead of NGO's, so the one implementation in the editor tests is fully qualified. - N4E's source generator errors on an assembly that does not reference N4E, so the editor test assembly now references it. Multiplayer Services 2.3.1 does not compile against N4E 7.0.0 and no fix is published, so it is dropped from the test project manifests. Validation moves to trunk, the only editor that has dropped N4E as a core package and can resolve the 7.0.0 request rather than its bundled 6.7.0. The unified work is preserved and still compiles with both defines set: the N4E 6.7.0 spellings are updated, and GhostObject.ApplyPostTransformMatrixScale, which N4E removed in its scale rework, is reimplemented over the new PostTransformMatrix model. The unified CI job sets the defines itself and is no longer a PR check. Also disables the serialization tests that fail under CoreCLR so the package is not ejected from the editor manifest batch. Parts of this are taken from #4156. --- .yamato/_triggers.yml | 3 +- .yamato/project.metafile | 7 ++- .yamato/unified-tests.yml | 13 +++--- com.unity.netcode.gameobjects/CHANGELOG.md | 4 ++ .../Editor/NetworkObjectEditor.cs | 3 +- .../Editor/Unity.Netcode.Editor.asmdef | 5 --- .../Components/AnticipatedNetworkTransform.cs | 8 ++-- .../Components/Helpers/NetworkObjectBridge.cs | 44 ++++++++++++++++++- .../Components/Helpers/UnifiedBootstrap.cs | 4 +- .../Helpers/UnifiedUpdateConnections.cs | 1 - .../Runtime/Core/NetworkBehaviour.cs | 4 +- .../Runtime/Core/NetworkManager.cs | 17 +++---- .../Runtime/Core/NetworkObject.cs | 1 - .../AnticipatedNetworkVariable.cs | 12 ++--- .../SceneManagement/NetworkSceneManager.cs | 22 +++++----- .../Runtime/Spawning/NetworkPrefabHandler.cs | 1 - .../Unified/UnifiedNetcodeTransport.cs | 13 +++--- .../Runtime/Unity.Netcode.Runtime.asmdef | 8 +--- .../Editor/Transports/UnityTransportTests.cs | 4 +- .../Editor/Unity.Netcode.Editor.Tests.asmdef | 1 + .../NetworkBehaviourReferenceTests.cs | 6 +++ .../NetworkObjectReferenceTests.cs | 9 ++++ .../TestHelpers/NetcodeIntegrationTest.cs | 11 ++--- .../Unity.Netcode.Runtime.Tests.asmdef | 5 --- com.unity.netcode.gameobjects/package.json | 3 +- .../Runtime/TestProject.Runtime.Tests.asmdef | 5 --- testproject/Packages/manifest-unified.json | 3 +- testproject/Packages/manifest.json | 1 - .../ProjectSettings/ProjectSettings.asset | 2 +- 29 files changed, 129 insertions(+), 91 deletions(-) diff --git a/.yamato/_triggers.yml b/.yamato/_triggers.yml index 2ed90b16ee..ce221f4e24 100644 --- a/.yamato/_triggers.yml +++ b/.yamato/_triggers.yml @@ -90,7 +90,8 @@ pr_code_changes_checks: # Note that our daily tests will anyway run both test configurations in "minimal supported" and "trunk" configurations - .yamato/desktop-standalone-tests.yml#desktop_standalone_test_testproject_ubuntu_il2cpp_{{ pinnedTrunk }} - .yamato/cmb-service-standalone-tests.yml#cmb_service_standalone_test_testproject_ubuntu_il2cpp_{{ pinnedTrunk }} - - .yamato/_run-all.yml#run_all_unified_tests + # The unified (NGO + N4E) tests are no longer a PR check: the unified API is behind N4E's own + # experimental define, so it is not part of what NGO ships. Still run nightly and on "/ci unified". # Run code coverage test (PRs use the pinned "safe" trunk) - .yamato/code-coverage.yml#code_coverage_project_test_testproject_ubuntu_{{ pinnedTrunk }} triggers: diff --git a/.yamato/project.metafile b/.yamato/project.metafile index 8c5b02077d..f5588b08b5 100644 --- a/.yamato/project.metafile +++ b/.yamato/project.metafile @@ -175,16 +175,19 @@ test_platforms: # Editors to be used for testing. NGOv3.X official support started from 6000.7 editor # TODO: When a new editor will be released it should be added to this list +# TEMPORARY: only trunk has dropped Netcode for Entities as a core package, so only there does the +# com.unity.netcode 7.0.0 dependency resolve - a released editor's bundled 6.7.0 wins over the request. +# Restore the released editors here once one ships without it. `all` is left alone as the reminder. validation_editors: default: - - 6000.7 + - trunk all: - 6000.7.0a6 - 6000.7 - trunk - 1d47644d0e359a8139ae6f99217da3c4e47f4779 minimal: - - 6000.7.0a6 + - trunk pinnedTrunk: 1d47644d0e359a8139ae6f99217da3c4e47f4779 diff --git a/.yamato/unified-tests.yml b/.yamato/unified-tests.yml index dfd88e702a..7cc0bc4234 100644 --- a/.yamato/unified-tests.yml +++ b/.yamato/unified-tests.yml @@ -10,9 +10,10 @@ # 2. For all unified editors (currently a single pinned alpha, see project.metafile) # QUALITY CONSIDERATIONS-------------------------------------------------------------------- - # TODO: the manifest swap means testproject/Packages/manifest-unified.json has to be kept in sync - # with manifest.json by hand. Revisit once N4E is a hard dependency of NGO and one manifest - # can cover both cases. + # TODO: N4E is now a hard dependency, so the manifest swap only pins the N4E version and the two + # manifests can be collapsed into one. + # This job is deliberately not part of the PR checks: N4E 7.0.0 ships the unified API behind its own + # experimental define, so nothing in the shipping configuration compiles it. #------------------------------------------------------------------------------------ @@ -36,9 +37,11 @@ unified_test_{{ project.name }}_{{ platform.name }}_{{ editor }}: UNIFIED_TESTS: "true" commands: - # Swap in the manifest that has the unified packages and versions required. - # Without the N4E package, UNIFIED_NETCODE is undefined and the unified API excluded. + # Swap in the manifest that pins the N4E version the unified API is written against. - cp {{ project.path }}/Packages/manifest-unified.json {{ project.path }}/Packages/manifest.json + # Turn the unified API on. UNIFIED_NETCODE is opt-in, and N4E keeps its GameObject bridge internal + # until NETCODE_GAMEOBJECT_BRIDGE_EXPERIMENTAL is defined, so both are needed here and nowhere else. + - sed -i "s/UNITY_NETCODE_NATIVE_COLLECTION_SUPPORT/UNITY_NETCODE_NATIVE_COLLECTION_SUPPORT;NETCODE_GAMEOBJECT_BRIDGE_EXPERIMENTAL;UNIFIED_NETCODE;OUT_OF_BAND_RPC/" {{ project.path }}/ProjectSettings/ProjectSettings.asset - unity-downloader-cli --fast --wait -u {{ editor }} -c Editor - UnifiedTestRunner --testproject={{ project.path }} --suite=playmode --artifacts-path=test-results --editor-location=.Editor --rerun-strategy=Test --retry={{ num_test_retries }} --clean-library-on-rerun --timeout={{ test_timeout }} artifacts: diff --git a/com.unity.netcode.gameobjects/CHANGELOG.md b/com.unity.netcode.gameobjects/CHANGELOG.md index c684359ce8..683130dd33 100644 --- a/com.unity.netcode.gameobjects/CHANGELOG.md +++ b/com.unity.netcode.gameobjects/CHANGELOG.md @@ -10,8 +10,12 @@ Additional documentation and release notes are available at [Multiplayer Documen ### Added +- Netcode for Entities (`com.unity.netcode` 7.0.0) is now a dependency, so installing Netcode for GameObjects also brings it, and its own dependencies (Entities, Burst, Collections), into the project. + ### Changed +- The `com.unity.transport` dependency moved from 2.6.0 to 6.5.0, the version Netcode for Entities 7.0.0 requires. + - Changed `NetworkTransform.UseHalfFloatPrecision` to synchronize position with a resolution of approximately 1mm regardless of how far an object has travelled. Previously the resolution could degrade to approximately 3cm. This does not increase bandwidth, but projects using `NetworkTransform.UseUnreliableDeltas` will send full precision position updates more often. (#4129) - All editor assembly definitions are renamed with `Unity.Netcode.GameObjects.x` variants diff --git a/com.unity.netcode.gameobjects/Editor/NetworkObjectEditor.cs b/com.unity.netcode.gameobjects/Editor/NetworkObjectEditor.cs index 2d3c7baafe..312e875850 100644 --- a/com.unity.netcode.gameobjects/Editor/NetworkObjectEditor.cs +++ b/com.unity.netcode.gameobjects/Editor/NetworkObjectEditor.cs @@ -1,7 +1,6 @@ using System.Collections.Generic; #if UNIFIED_NETCODE -using Unity.NetCode; -using Unity.NetCode.Editor; +using Unity.Netcode.Editor; #endif using UnityEditor; using UnityEngine; diff --git a/com.unity.netcode.gameobjects/Editor/Unity.Netcode.Editor.asmdef b/com.unity.netcode.gameobjects/Editor/Unity.Netcode.Editor.asmdef index ca7c2e6e26..36c3483abc 100644 --- a/com.unity.netcode.gameobjects/Editor/Unity.Netcode.Editor.asmdef +++ b/com.unity.netcode.gameobjects/Editor/Unity.Netcode.Editor.asmdef @@ -46,11 +46,6 @@ "expression": "0.2.0", "define": "MULTIPLAYER_SERVICES_SDK_INSTALLED" }, - { - "name": "com.unity.netcode", - "expression": "1.10.1", - "define": "UNIFIED_NETCODE" - }, { "name": "com.unity.multiplayer.playmode", "expression": "0.1.0", diff --git a/com.unity.netcode.gameobjects/Runtime/Components/AnticipatedNetworkTransform.cs b/com.unity.netcode.gameobjects/Runtime/Components/AnticipatedNetworkTransform.cs index 26d1e939e2..55898ac31c 100644 --- a/com.unity.netcode.gameobjects/Runtime/Components/AnticipatedNetworkTransform.cs +++ b/com.unity.netcode.gameobjects/Runtime/Components/AnticipatedNetworkTransform.cs @@ -21,13 +21,13 @@ namespace Unity.Netcode.Components /// resulting in a "snap" to the new value if it is different from the anticipated value. /// /// Smooth: In this mode (with set to - /// and an callback that calls + /// and an callback that calls /// from the anticipated value to the authority value with an appropriate /// -style smooth function), when a more up-to-date value is received from the authority, /// it will interpolate over time from an incorrect anticipated value to the correct authoritative value. /// /// Constant Reanticipation: In this mode (with set to - /// and an that calculates a + /// and an that calculates a /// new anticipated value based on the current authoritative value), when a more up-to-date value is received from /// the authority, user code calculates a new anticipated value, possibly calling to interpolate /// between the previous anticipation and the new anticipation. This is useful for values that change frequently and @@ -101,11 +101,11 @@ private void Reset() /// Defines what the behavior should be if we receive a value from the server with an earlier associated /// time value than the anticipation time value. ///

- /// If this is , the stale data will be ignored and the authoritative + /// If this is , the stale data will be ignored and the authoritative /// value will not replace the anticipated value until the anticipation time is reached. /// and will also not be invoked for this stale data. ///

- /// If this is , the stale data will replace the anticipated data and + /// If this is , the stale data will replace the anticipated data and /// and will be invoked. /// In this case, the authoritativeTime value passed to will be lower than /// the anticipationTime value, and that callback can be used to calculate a new anticipated value. diff --git a/com.unity.netcode.gameobjects/Runtime/Components/Helpers/NetworkObjectBridge.cs b/com.unity.netcode.gameobjects/Runtime/Components/Helpers/NetworkObjectBridge.cs index 69eb729d9a..2eb69c88fb 100644 --- a/com.unity.netcode.gameobjects/Runtime/Components/Helpers/NetworkObjectBridge.cs +++ b/com.unity.netcode.gameobjects/Runtime/Components/Helpers/NetworkObjectBridge.cs @@ -1,5 +1,6 @@ #if UNIFIED_NETCODE -using Unity.NetCode; +using Unity.Mathematics; +using Unity.Transforms; using UnityEngine; namespace Unity.Netcode @@ -13,7 +14,9 @@ namespace Unity.Netcode [DefaultExecutionOrder(GhostObject.ExecutionOrder + 1)] //BREAK --- Fix this on UNIFIED side 1st - public partial class NetworkObjectBridge : GhostBehaviour + // Internal: GhostBehaviour is only public when NETCODE_GAMEOBJECT_BRIDGE_EXPERIMENTAL is defined, and a public + // type cannot derive from an internal one. + internal partial class NetworkObjectBridge : GhostBehaviour { // DefaultExecutionOrder // TODO: Define a const for the value used on GhostObject and use that value @@ -83,5 +86,42 @@ internal void ApplyScale(Vector3 scale) Ghost.ApplyPostTransformMatrixScale(scale); } } + + /// + /// Stands in for N4E's GhostObject.ApplyPostTransformMatrixScale, removed by the 6.7.0 non-uniform + /// scale rework that gave the GameObject-to-entity transform sync ownership of the + /// . Remove this once N4E exposes a supported way to push scale to a ghost. + /// + internal static class GhostObjectScaleExtensions + { + /// + /// A ghost that replicates 3D scale stores it in its and holds + /// at 1, because consumers multiply the two. A ghost authored with + /// UseUniformScale has no matrix - and cannot gain one at runtime, since the component is only in the + /// replicated set when the prefab is registered - so only the uniform scale can be applied there. + /// + internal static void ApplyPostTransformMatrixScale(this GhostObject ghost, Vector3 scale) + { + var entityManager = ghost.World.EntityManager; + var entity = ghost.Entity; + var localTransform = entityManager.GetComponentData(entity); + + if (entityManager.HasComponent(entity)) + { + entityManager.SetComponentData(entity, new PostTransformMatrix { Value = float4x4.Scale(scale) }); + localTransform.Scale = 1f; + } + else + { + if (!Mathf.Approximately(scale.x, scale.y) || !Mathf.Approximately(scale.y, scale.z)) + { + Debug.LogWarning($"[{nameof(NetworkObjectBridge)}] Non-uniform scale {scale} cannot be replicated by a ghost authored for uniform scale; applying {scale.x} to all axes.", ghost); + } + localTransform.Scale = scale.x; + } + + entityManager.SetComponentData(entity, localTransform); + } + } } #endif diff --git a/com.unity.netcode.gameobjects/Runtime/Components/Helpers/UnifiedBootstrap.cs b/com.unity.netcode.gameobjects/Runtime/Components/Helpers/UnifiedBootstrap.cs index 8b99dce5aa..8c9167de54 100644 --- a/com.unity.netcode.gameobjects/Runtime/Components/Helpers/UnifiedBootstrap.cs +++ b/com.unity.netcode.gameobjects/Runtime/Components/Helpers/UnifiedBootstrap.cs @@ -1,7 +1,9 @@ +#if UNIFIED_NETCODE && !NETCODE_GAMEOBJECT_BRIDGE_EXPERIMENTAL +#error UNIFIED_NETCODE also requires NETCODE_GAMEOBJECT_BRIDGE_EXPERIMENTAL: Netcode for Entities keeps its GameObject bridge (GhostObject, GhostBehaviour, GhostField) internal until that define is set. +#endif #if UNIFIED_NETCODE using System; using Unity.Entities; -using Unity.NetCode; using UnityEngine; namespace Unity.Netcode diff --git a/com.unity.netcode.gameobjects/Runtime/Components/Helpers/UnifiedUpdateConnections.cs b/com.unity.netcode.gameobjects/Runtime/Components/Helpers/UnifiedUpdateConnections.cs index e9b66ba877..513f84cfc7 100644 --- a/com.unity.netcode.gameobjects/Runtime/Components/Helpers/UnifiedUpdateConnections.cs +++ b/com.unity.netcode.gameobjects/Runtime/Components/Helpers/UnifiedUpdateConnections.cs @@ -2,7 +2,6 @@ using System.Collections.Generic; using Unity.Collections; using Unity.Entities; -using Unity.NetCode; using UnityEngine; namespace Unity.Netcode.Components diff --git a/com.unity.netcode.gameobjects/Runtime/Core/NetworkBehaviour.cs b/com.unity.netcode.gameobjects/Runtime/Core/NetworkBehaviour.cs index b05578fed0..5d1a04537b 100644 --- a/com.unity.netcode.gameobjects/Runtime/Core/NetworkBehaviour.cs +++ b/com.unity.netcode.gameobjects/Runtime/Core/NetworkBehaviour.cs @@ -917,7 +917,7 @@ internal void InternalOnNetworkDespawn() } /// - /// In client-server contexts, this method is invoked on both the server and the local client of the owner when ownership is assigned. + /// In client-server contexts, this method is invoked on both the server and the local client of the owner when ownership is assigned. /// In distributed authority contexts, this method is invoked on all clients connected to the session. /// public virtual void OnGainedOwnership() { } @@ -952,7 +952,7 @@ internal void InternalOnOwnershipChanged(ulong previous, ulong current) } /// - /// In client-server contexts, this method is invoked on the local client when it loses ownership of the associated + /// In client-server contexts, this method is invoked on the local client when it loses ownership of the associated /// and on the server when any client loses ownership. /// In distributed authority contexts, this method is invoked on all clients connected to the session. /// diff --git a/com.unity.netcode.gameobjects/Runtime/Core/NetworkManager.cs b/com.unity.netcode.gameobjects/Runtime/Core/NetworkManager.cs index 3c5600afa5..c21af7dd39 100644 --- a/com.unity.netcode.gameobjects/Runtime/Core/NetworkManager.cs +++ b/com.unity.netcode.gameobjects/Runtime/Core/NetworkManager.cs @@ -4,11 +4,6 @@ using Unity.Collections; #if UNIFIED_NETCODE using Unity.Entities; -// Netcode for Entities' namespace differs from this one only by the casing of a single letter, so a -// blanket import of it competes with Unity.Netcode on every name the two happen to share. Importing -// only the types used here keeps that surface to exactly those names. -using NetCodeConfig = Unity.NetCode.NetCodeConfig; -using NetcodeWorld = Unity.NetCode.NetcodeWorld; #endif using Unity.Netcode.Components; using Unity.Netcode.GameObjects.Timing; @@ -1375,13 +1370,13 @@ internal void InitializeNetcodeWorld() if (this == Singleton) { - if (NetCode.Netcode.IsActive) + if (Netcode.IsActive) { Log.Info(new Context(LogLevel.Normal, "Netcode is not active but has an instance at this point.")); } /// !! Important !! /// Clear out any pre-existing configuration in the event this applicatioin instance has already been connected to a session. - NetCode.Netcode.Reset(); + Netcode.Reset(); } /// !! Initialize worlds here !! @@ -1396,14 +1391,14 @@ internal void InitializeNetcodeWorld() /// True if the configuration is correct; otherwise, false. private bool UnifiedIsConfiguredCorrectly() { - if (NetCodeConfig.Global == null) + if (NetcodeConfig.Global == null) { - Log.Error(new Context(LogLevel.Error, $"You must create a {nameof(NetCodeConfig)} and set it to a single world in order to run in hybrid mode!").AddTag("Unified")); + Log.Error(new Context(LogLevel.Error, $"You must create a {nameof(NetcodeConfig)} and set it to a single world in order to run in hybrid mode!").AddTag("Unified")); return false; } - if (NetCodeConfig.Global.HostWorldModeSelection != NetCodeConfig.HostWorldMode.SingleWorld) + if (NetcodeConfig.Global.HostWorldModeSelection != NetcodeConfig.HostWorldMode.SingleWorld) { - Log.Error(new Context(LogLevel.Error, $"You must configure {nameof(NetCodeConfig)} to only use a single world in order to run in hybrid mode!").AddTag("Unified")); + Log.Error(new Context(LogLevel.Error, $"You must configure {nameof(NetcodeConfig)} to only use a single world in order to run in hybrid mode!").AddTag("Unified")); return false; } return true; diff --git a/com.unity.netcode.gameobjects/Runtime/Core/NetworkObject.cs b/com.unity.netcode.gameobjects/Runtime/Core/NetworkObject.cs index 2ec3eedacf..8d893a78f0 100644 --- a/com.unity.netcode.gameobjects/Runtime/Core/NetworkObject.cs +++ b/com.unity.netcode.gameobjects/Runtime/Core/NetworkObject.cs @@ -8,7 +8,6 @@ using Unity.Netcode.Logging; using Unity.Netcode.Runtime; #if UNIFIED_NETCODE -using Unity.NetCode; #endif #if UNITY_EDITOR diff --git a/com.unity.netcode.gameobjects/Runtime/NetworkVariable/AnticipatedNetworkVariable.cs b/com.unity.netcode.gameobjects/Runtime/NetworkVariable/AnticipatedNetworkVariable.cs index a09314e8cb..1cfab08e12 100644 --- a/com.unity.netcode.gameobjects/Runtime/NetworkVariable/AnticipatedNetworkVariable.cs +++ b/com.unity.netcode.gameobjects/Runtime/NetworkVariable/AnticipatedNetworkVariable.cs @@ -33,18 +33,18 @@ public enum StaleDataHandling /// /// /// Snap: In this mode (with set to - /// and no callback), + /// and no callback), /// the moment a more up-to-date value is received from the authority, it will simply replace the anticipated value, /// resulting in a "snap" to the new value if it is different from the anticipated value. /// /// Smooth: In this mode (with set to - /// and an callback that calls + /// and an callback that calls /// from the anticipated value to the authority value with an appropriate /// -style smooth function), when a more up-to-date value is received from the authority, /// it will interpolate over time from an incorrect anticipated value to the correct authoritative value. /// /// Constant Reanticipation: In this mode (with set to - /// and an that calculates a + /// and an that calculates a /// new anticipated value based on the current authoritative value), when a more up-to-date value is received from /// the authority, user code calculates a new anticipated value, possibly calling to interpolate /// between the previous anticipation and the new anticipation. This is useful for values that change frequently and @@ -85,11 +85,11 @@ public class AnticipatedNetworkVariable : NetworkVariableBase /// Defines what the behavior should be if we receive a value from the server with an earlier associated /// time value than the anticipation time value. ///

- /// If this is , the stale data will be ignored and the authoritative + /// If this is , the stale data will be ignored and the authoritative /// value will not replace the anticipated value until the anticipation time is reached. /// and will also not be invoked for this stale data. ///

- /// If this is , the stale data will replace the anticipated data and + /// If this is , the stale data will replace the anticipated data and /// and will be invoked. /// In this case, the authoritativeTime value passed to will be lower than /// the anticipationTime value, and that callback can be used to calculate a new anticipated value. @@ -229,7 +229,7 @@ public void Anticipate(T value) /// Retrieves or sets the underlying authoritative value. /// Note that only a client or server with write permissions to this variable may set this value. /// When this variable has been anticipated, this value will alawys return the most recent authoritative - /// state, which is updated even if is . + /// state, which is updated even if is . /// #pragma warning restore IDE0001 public T AuthoritativeValue diff --git a/com.unity.netcode.gameobjects/Runtime/SceneManagement/NetworkSceneManager.cs b/com.unity.netcode.gameobjects/Runtime/SceneManagement/NetworkSceneManager.cs index 8ee61a95ab..cafce0f7c1 100644 --- a/com.unity.netcode.gameobjects/Runtime/SceneManagement/NetworkSceneManager.cs +++ b/com.unity.netcode.gameobjects/Runtime/SceneManagement/NetworkSceneManager.cs @@ -23,7 +23,7 @@ public class SceneEvent { /// /// The returned by
- /// This is set for the following s: + /// This is set for the following s: /// /// /// @@ -32,13 +32,13 @@ public class SceneEvent public AsyncOperation AsyncOperation; /// - /// Will always be set to the current + /// Will always be set to the current /// public SceneEventType SceneEventType; /// /// If applicable, this reflects the type of scene loading or unloading that is occurring.
- /// This is set for the following s: + /// This is set for the following s: /// /// /// @@ -52,7 +52,7 @@ public class SceneEvent /// /// This will be set to the scene name that the event pertains to.
- /// This is set for the following s: + /// This is set for the following s: /// /// /// @@ -66,7 +66,7 @@ public class SceneEvent /// /// This will be set to the path to the scene that the event pertains to.
- /// This is set for the following s: + /// This is set for the following s: /// /// /// @@ -80,7 +80,7 @@ public class SceneEvent /// /// When a scene is loaded, the Scene structure is returned.
- /// This is set for the following s: + /// This is set for the following s: /// /// /// @@ -90,7 +90,7 @@ public class SceneEvent /// /// The client identifier can vary depending upon the following conditions:
/// - /// s that always set the + /// s that always set the /// to the local client identifier, are initiated (and processed locally) by the /// server-host, and sent to all clients to be processed.
/// @@ -122,7 +122,7 @@ public class SceneEvent /// /// List of clients that completed a loading or unloading event.
- /// This is set for the following s: + /// This is set for the following s: /// /// /// @@ -132,7 +132,7 @@ public class SceneEvent /// /// List of clients that timed out during a loading or unloading event.
- /// This is set for the following s: + /// This is set for the following s: /// /// /// @@ -824,7 +824,7 @@ public void SetClientSynchronizationMode(LoadSceneMode mode) /// /// Constructor /// - /// one instance per instance + /// one instance per instance /// maximum pool size internal NetworkSceneManager(NetworkManager networkManager) { @@ -2693,7 +2693,7 @@ internal void HandleSceneEvent(ulong clientId, FastBufferReader reader) } else { - Debug.LogError($"{nameof(HandleSceneEvent)} was invoked but {nameof(Netcode.NetworkManager)} reference was null!"); + Debug.LogError($"{nameof(HandleSceneEvent)} was invoked but {nameof(NetworkManager)} reference was null!"); } } diff --git a/com.unity.netcode.gameobjects/Runtime/Spawning/NetworkPrefabHandler.cs b/com.unity.netcode.gameobjects/Runtime/Spawning/NetworkPrefabHandler.cs index 7b902a3a52..e4c69bfdad 100644 --- a/com.unity.netcode.gameobjects/Runtime/Spawning/NetworkPrefabHandler.cs +++ b/com.unity.netcode.gameobjects/Runtime/Spawning/NetworkPrefabHandler.cs @@ -1,7 +1,6 @@ using System; using System.Collections.Generic; #if UNIFIED_NETCODE -using Unity.NetCode; #endif using UnityEngine; diff --git a/com.unity.netcode.gameobjects/Runtime/Transports/Unified/UnifiedNetcodeTransport.cs b/com.unity.netcode.gameobjects/Runtime/Transports/Unified/UnifiedNetcodeTransport.cs index c9fda0cd31..b8509f4ea6 100644 --- a/com.unity.netcode.gameobjects/Runtime/Transports/Unified/UnifiedNetcodeTransport.cs +++ b/com.unity.netcode.gameobjects/Runtime/Transports/Unified/UnifiedNetcodeTransport.cs @@ -6,7 +6,6 @@ using Unity.Collections; using Unity.Collections.LowLevel.Unsafe; using Unity.Entities; -using Unity.NetCode; using Unity.Netcode.GameObjects.Timing; using Unity.Netcode.Transports.UTP; using UnityEngine; @@ -273,7 +272,7 @@ public override NetworkEvent PollEvent(out ulong clientId, out ArraySegment(connection.ConnectionEntity); } - private void OnServerNewClientConnection(Connection connection, NetCodeConnectionEvent connectionEvent) + private void OnServerNewClientConnection(Connection connection, NetcodeConnectionEvent connectionEvent) { m_Connections[connectionEvent.Id.Value] = new ConnectionInfo { @@ -365,7 +364,7 @@ private DisconnectEvents GetDisconnectEventFromNetworkStreamDisconnectReason(Net return DisconnectEvents.Disconnected; } - private void OnClientDisconnectFromServer(Connection connection, NetCodeConnectionEvent connectionEvent) + private void OnClientDisconnectFromServer(Connection connection, NetcodeConnectionEvent connectionEvent) { SetDisconnectEvent( GetDisconnectEventFromNetworkStreamDisconnectReason(connectionEvent.DisconnectReason), @@ -374,12 +373,12 @@ private void OnClientDisconnectFromServer(Connection connection, NetCodeConnecti InvokeOnTransportEvent(NetworkEvent.Disconnect, (ulong)connectionEvent.Id.Value, default, m_RealTimeProvider.RealTimeSinceStartup); } - private void OnServerClientDisconnected(Connection connection, NetCodeConnectionEvent connectionEvent) + private void OnServerClientDisconnected(Connection connection, NetcodeConnectionEvent connectionEvent) { InvokeOnTransportEvent(NetworkEvent.Disconnect, (ulong)connectionEvent.Id.Value, default, m_RealTimeProvider.RealTimeSinceStartup); } - private void OnClientConnectionEvent(Connection connection, NetCodeConnectionEvent connectionEvent) + private void OnClientConnectionEvent(Connection connection, NetcodeConnectionEvent connectionEvent) { switch (connectionEvent.State) { @@ -392,7 +391,7 @@ private void OnClientConnectionEvent(Connection connection, NetCodeConnectionEve } } - private void OnServerConnectionEvent(Connection connection, NetCodeConnectionEvent connectionEvent) + private void OnServerConnectionEvent(Connection connection, NetcodeConnectionEvent connectionEvent) { switch (connectionEvent.State) { diff --git a/com.unity.netcode.gameobjects/Runtime/Unity.Netcode.Runtime.asmdef b/com.unity.netcode.gameobjects/Runtime/Unity.Netcode.Runtime.asmdef index 6b32d4a1b2..e5d50997cc 100644 --- a/com.unity.netcode.gameobjects/Runtime/Unity.Netcode.Runtime.asmdef +++ b/com.unity.netcode.gameobjects/Runtime/Unity.Netcode.Runtime.asmdef @@ -15,7 +15,8 @@ "Unity.Burst", "Unity.Mathematics", "GUID:953adc2a6b8b4e3c8df5b728bcd546e9", - "Unity.Entities" + "Unity.Entities", + "Unity.Transforms" ], "includePlatforms": [], "excludePlatforms": [], @@ -90,11 +91,6 @@ "expression": "6000.5.0a1", "define": "SCENE_MANAGEMENT_SCENE_HANDLE_MUST_USE_ULONG" }, - { - "name": "com.unity.netcode", - "expression": "1.10.1", - "define": "UNIFIED_NETCODE" - }, { "name": "com.unity.multiplayer.playmode", "expression": "0.1.0", diff --git a/com.unity.netcode.gameobjects/Tests/Editor/Transports/UnityTransportTests.cs b/com.unity.netcode.gameobjects/Tests/Editor/Transports/UnityTransportTests.cs index 22e075eec1..5ddb3aaeb3 100644 --- a/com.unity.netcode.gameobjects/Tests/Editor/Transports/UnityTransportTests.cs +++ b/com.unity.netcode.gameobjects/Tests/Editor/Transports/UnityTransportTests.cs @@ -231,7 +231,9 @@ public void UnityTransport_HostnameValidation((string, bool) testCase) } #endif - private class IPCDriverConstructor : INetworkStreamDriverConstructor + // Fully qualified: Netcode for Entities declares an INetworkStreamDriverConstructor of its own in the + // Unity.Netcode root, which the enclosing namespace resolves ahead of the using directive above. + private class IPCDriverConstructor : Unity.Netcode.Transports.UTP.INetworkStreamDriverConstructor { public void CreateDriver( UnityTransport transport, diff --git a/com.unity.netcode.gameobjects/Tests/Editor/Unity.Netcode.Editor.Tests.asmdef b/com.unity.netcode.gameobjects/Tests/Editor/Unity.Netcode.Editor.Tests.asmdef index a9a05da02b..c56c041e1e 100644 --- a/com.unity.netcode.gameobjects/Tests/Editor/Unity.Netcode.Editor.Tests.asmdef +++ b/com.unity.netcode.gameobjects/Tests/Editor/Unity.Netcode.Editor.Tests.asmdef @@ -5,6 +5,7 @@ "Unity.Collections", "Unity.Netcode.Runtime", "Unity.Netcode.GameObjects.Editor", + "GUID:953adc2a6b8b4e3c8df5b728bcd546e9", "Unity.Multiplayer.MetricTypes", "Unity.Multiplayer.NetStats", "Unity.Multiplayer.Tools.MetricTypes", diff --git a/com.unity.netcode.gameobjects/Tests/Runtime/Serialization/NetworkBehaviourReferenceTests.cs b/com.unity.netcode.gameobjects/Tests/Runtime/Serialization/NetworkBehaviourReferenceTests.cs index 1306b4a803..9248ed159f 100644 --- a/com.unity.netcode.gameobjects/Tests/Runtime/Serialization/NetworkBehaviourReferenceTests.cs +++ b/com.unity.netcode.gameobjects/Tests/Runtime/Serialization/NetworkBehaviourReferenceTests.cs @@ -57,6 +57,9 @@ public IEnumerator TestRpcImplicitNetworkBehaviour() #region Tests using non-null NetworkBehaviours and NetworkVariable [UnityTest] +#if ENABLE_CORECLR + [Explicit("NGO NetworkVariable serialization codegen not generated for some types on CoreCLR (falls back to FallbackSerializer), see https://jira.unity3d.com/browse/UUM-149592")] +#endif public IEnumerator TestNetworkVariable() { yield return SpawnTestPrefabInstance(); @@ -75,6 +78,9 @@ public IEnumerator TestNetworkVariable() #region Validating using NULL as a NetworkBehaviourReference [UnityTest] +#if ENABLE_CORECLR + [Explicit("NGO NetworkVariable serialization codegen not generated for some types on CoreCLR (falls back to FallbackSerializer), see https://jira.unity3d.com/browse/UUM-149592")] +#endif public IEnumerator TestSerializeNull() { yield return SpawnTestPrefabInstance(true); diff --git a/com.unity.netcode.gameobjects/Tests/Runtime/Serialization/NetworkObjectReferenceTests.cs b/com.unity.netcode.gameobjects/Tests/Runtime/Serialization/NetworkObjectReferenceTests.cs index 139a4a9e4f..8d6122a27b 100644 --- a/com.unity.netcode.gameobjects/Tests/Runtime/Serialization/NetworkObjectReferenceTests.cs +++ b/com.unity.netcode.gameobjects/Tests/Runtime/Serialization/NetworkObjectReferenceTests.cs @@ -34,6 +34,9 @@ protected override void OnOneTimeSetup() } [UnityTest] +#if ENABLE_CORECLR + [Explicit("NGO NetworkVariable serialization codegen not generated for some types on CoreCLR (falls back to FallbackSerializer), see https://jira.unity3d.com/browse/UUM-149592")] +#endif public IEnumerator TestSerializeNetworkObject() { yield return SpawnTestPrefabInstance(); @@ -61,6 +64,9 @@ public IEnumerator TestSerializeNetworkObject() } [UnityTest] +#if ENABLE_CORECLR + [Explicit("NGO NetworkVariable serialization codegen not generated for some types on CoreCLR (falls back to FallbackSerializer), see https://jira.unity3d.com/browse/UUM-149592")] +#endif public IEnumerator TestSerializeNull() { yield return SpawnTestPrefabInstance(true); @@ -108,6 +114,9 @@ public IEnumerator TestSerializeNull() } [UnityTest] +#if ENABLE_CORECLR + [Explicit("NGO NetworkVariable serialization codegen not generated for some types on CoreCLR (falls back to FallbackSerializer), see https://jira.unity3d.com/browse/UUM-149592")] +#endif public IEnumerator TestGetReferenceAndConversion() { yield return SpawnTestPrefabInstance(); diff --git a/com.unity.netcode.gameobjects/Tests/Runtime/TestHelpers/NetcodeIntegrationTest.cs b/com.unity.netcode.gameobjects/Tests/Runtime/TestHelpers/NetcodeIntegrationTest.cs index 6dbf9fe2e1..18ea591472 100644 --- a/com.unity.netcode.gameobjects/Tests/Runtime/TestHelpers/NetcodeIntegrationTest.cs +++ b/com.unity.netcode.gameobjects/Tests/Runtime/TestHelpers/NetcodeIntegrationTest.cs @@ -6,9 +6,6 @@ using System.Runtime.CompilerServices; using System.Text; using NUnit.Framework; -#if UNIFIED_NETCODE -using Unity.NetCode; -#endif using Unity.Netcode.GameObjects.Timing; using Unity.Netcode.RuntimeTests; using Unity.Netcode.Transports.UTP; @@ -2651,11 +2648,11 @@ internal void SpawnInstanceWithOwnership(NetworkObject networkObjectToSpawn, Net else { #if UNIFIED_NETCODE - // TODO-FixMe: NetCode.Netcode.Instance is a singleton and might cause issues + // TODO-FixMe: Netcode.Instance is a singleton and might cause issues // assigning this. if (networkObjectToSpawn.HasGhost) { - NetCode.Netcode.Instance.m_ActiveWorld = m_ServerNetworkManager.NetcodeWorld; + Netcode.Instance.m_ActiveWorld = m_ServerNetworkManager.NetcodeWorld; } #endif networkObjectToSpawn.NetworkManagerOwner = m_ServerNetworkManager; // Required to assure the server does the spawning @@ -2723,10 +2720,10 @@ private GameObject SpawnObject(NetworkObject prefabNetworkObject, NetworkManager // N4E's rate managers reassign that singleton on every world update, so by the time a test body runs // it points at whichever world updated last - typically a client world - and the spawn is rejected with // "You can only spawn a ghost on a server or during prediction on a client." - // TODO-UNIFIED: NetCode.Netcode.Instance is a singleton and might cause issues assigning this. + // TODO-UNIFIED: Netcode.Instance is a singleton and might cause issues assigning this. if (prefabNetworkObject.HasGhost) { - NetCode.Netcode.Instance.m_ActiveWorld = m_ServerNetworkManager.NetcodeWorld; + Netcode.Instance.m_ActiveWorld = m_ServerNetworkManager.NetcodeWorld; } #endif var newInstance = Object.Instantiate(prefabNetworkObject.gameObject); diff --git a/com.unity.netcode.gameobjects/Tests/Runtime/Unity.Netcode.Runtime.Tests.asmdef b/com.unity.netcode.gameobjects/Tests/Runtime/Unity.Netcode.Runtime.Tests.asmdef index af36db6c11..d620159256 100644 --- a/com.unity.netcode.gameobjects/Tests/Runtime/Unity.Netcode.Runtime.Tests.asmdef +++ b/com.unity.netcode.gameobjects/Tests/Runtime/Unity.Netcode.Runtime.Tests.asmdef @@ -49,11 +49,6 @@ "name": "Unity", "expression": "6000.1.0a1", "define": "HOSTNAME_RESOLUTION_AVAILABLE" - }, - { - "name": "com.unity.netcode", - "expression": "1.10.1", - "define": "UNIFIED_NETCODE" } ], "noEngineReferences": false diff --git a/com.unity.netcode.gameobjects/package.json b/com.unity.netcode.gameobjects/package.json index bc60d24511..4c081beac9 100644 --- a/com.unity.netcode.gameobjects/package.json +++ b/com.unity.netcode.gameobjects/package.json @@ -7,7 +7,8 @@ "unityRelease": "0a6", "dependencies": { "com.unity.nuget.mono-cecil": "1.11.4", - "com.unity.transport": "2.6.0" + "com.unity.transport": "6.5.0", + "com.unity.netcode": "7.0.0" }, "samples": [ { diff --git a/testproject/Assets/Tests/Runtime/TestProject.Runtime.Tests.asmdef b/testproject/Assets/Tests/Runtime/TestProject.Runtime.Tests.asmdef index 51b61982a5..38af444a61 100644 --- a/testproject/Assets/Tests/Runtime/TestProject.Runtime.Tests.asmdef +++ b/testproject/Assets/Tests/Runtime/TestProject.Runtime.Tests.asmdef @@ -33,11 +33,6 @@ "name": "com.unity.addressables", "expression": "", "define": "TESTPROJECT_USE_ADDRESSABLES" - }, - { - "name": "com.unity.netcode", - "expression": "1.10.1", - "define": "UNIFIED_NETCODE" } ], "noEngineReferences": false diff --git a/testproject/Packages/manifest-unified.json b/testproject/Packages/manifest-unified.json index d38dd4e6e0..bffa344441 100644 --- a/testproject/Packages/manifest-unified.json +++ b/testproject/Packages/manifest-unified.json @@ -8,11 +8,10 @@ "com.unity.ide.visualstudio": "2.0.26", "com.unity.mathematics": "1.4.0", "com.unity.multiplayer.tools": "2.2.11", - "com.unity.netcode": "6.7.0", + "com.unity.netcode": "7.0.0", "com.unity.netcode.gameobjects": "file:../../com.unity.netcode.gameobjects", "com.unity.package-validation-suite": "0.49.0-preview", "com.unity.services.authentication": "3.7.4", - "com.unity.services.multiplayer": "2.3.1", "com.unity.test-framework": "1.9.0", "com.unity.test-framework.performance": "6.7.0", "com.unity.timeline": "6.7.0", diff --git a/testproject/Packages/manifest.json b/testproject/Packages/manifest.json index eb043b44fc..667015e6db 100644 --- a/testproject/Packages/manifest.json +++ b/testproject/Packages/manifest.json @@ -11,7 +11,6 @@ "com.unity.netcode.gameobjects": "file:../../com.unity.netcode.gameobjects", "com.unity.package-validation-suite": "0.49.0-preview", "com.unity.services.authentication": "3.7.4", - "com.unity.services.multiplayer": "2.3.1", "com.unity.test-framework": "1.9.0", "com.unity.test-framework.performance": "6.7.0", "com.unity.timeline": "6.7.0", diff --git a/testproject/ProjectSettings/ProjectSettings.asset b/testproject/ProjectSettings/ProjectSettings.asset index 7919f1cd96..3fcaa09986 100644 --- a/testproject/ProjectSettings/ProjectSettings.asset +++ b/testproject/ProjectSettings/ProjectSettings.asset @@ -741,7 +741,7 @@ PlayerSettings: webWasm2023: 0 webEnableSubmoduleStrippingCompatibility: 0 scriptingDefineSymbols: - Standalone: UNITY_NETCODE_NATIVE_COLLECTION_SUPPORT;NETCODE_GAMEOBJECT_BRIDGE_EXPERIMENTAL;NETCODE_EXPERIMENTAL_SINGLE_WORLD_HOST;OUT_OF_BAND_RPC + Standalone: UNITY_NETCODE_NATIVE_COLLECTION_SUPPORT additionalCompilerArguments: Standalone: [] platformArchitecture: {} From 45db9fcdf7d5eb2ce4f9d0e11810156c87e3f943 Mon Sep 17 00:00:00 2001 From: Noel Stephens Date: Tue, 8 Sep 2026 12:31:00 -0500 Subject: [PATCH 2/4] chore: fix the standards check for the n4e 7.0.0 dependency Three things the standards job caught, since it opens the project, runs the formatter with --fix and then fails on any diff at all: - The fully qualified INetworkStreamDriverConstructor is simplified by the formatter (IDE0001), so write it the way the formatter wants. It still resolves to NGO's, since the lookup walks out to Unity.Netcode.Transports before reaching the shared root. - N4E 7.0.0 renamed the serialized GlobalNetCodeConfig field to GlobalNetcodeConfig, which the editor rewrites in the test project's settings asset the first time it loads it. - validation_editors.minimal is back on a released editor. The standards job opens the project with it, and trunk rewrites ProjectVersion.txt out from under the cleanliness check. Nothing there needs N4E present: a released editor bundles 6.7.0 as a built-in package, so the 7.0.0 request is dropped silently and the project builds with no N4E at all - verified on 6000.7.0a6, which resolves and compiles clean with N4E absent from packages-lock, PackageCache and ScriptAssemblies alike. --- .yamato/project.metafile | 10 +++++++--- .../Tests/Editor/Transports/UnityTransportTests.cs | 4 ++-- .../NetCodeClientAndServerSettings.asset | 2 +- 3 files changed, 10 insertions(+), 6 deletions(-) diff --git a/.yamato/project.metafile b/.yamato/project.metafile index f5588b08b5..8f5417cea8 100644 --- a/.yamato/project.metafile +++ b/.yamato/project.metafile @@ -176,8 +176,12 @@ test_platforms: # TODO: When a new editor will be released it should be added to this list # TEMPORARY: only trunk has dropped Netcode for Entities as a core package, so only there does the -# com.unity.netcode 7.0.0 dependency resolve - a released editor's bundled 6.7.0 wins over the request. -# Restore the released editors here once one ships without it. `all` is left alone as the reminder. +# com.unity.netcode 7.0.0 dependency resolve. A released editor bundles 6.7.0 as a built-in package and +# UPM then drops the 7.0.0 request silently, leaving N4E out of the project entirely - which still +# compiles, since the unified API is opt-in. `default` runs the jobs that should see N4E present. +# `minimal` stays on a released editor: it is what the standards job opens the project with, and trunk +# rewrites ProjectVersion.txt out from under the cleanliness check. Restore `default` once a released +# editor ships without N4E as a core package; `all` is left alone as the reminder. validation_editors: default: - trunk @@ -187,7 +191,7 @@ validation_editors: - trunk - 1d47644d0e359a8139ae6f99217da3c4e47f4779 minimal: - - trunk + - 6000.7.0a6 pinnedTrunk: 1d47644d0e359a8139ae6f99217da3c4e47f4779 diff --git a/com.unity.netcode.gameobjects/Tests/Editor/Transports/UnityTransportTests.cs b/com.unity.netcode.gameobjects/Tests/Editor/Transports/UnityTransportTests.cs index 5ddb3aaeb3..bf5e3f15a1 100644 --- a/com.unity.netcode.gameobjects/Tests/Editor/Transports/UnityTransportTests.cs +++ b/com.unity.netcode.gameobjects/Tests/Editor/Transports/UnityTransportTests.cs @@ -231,9 +231,9 @@ public void UnityTransport_HostnameValidation((string, bool) testCase) } #endif - // Fully qualified: Netcode for Entities declares an INetworkStreamDriverConstructor of its own in the + // Qualified: Netcode for Entities declares an INetworkStreamDriverConstructor of its own in the // Unity.Netcode root, which the enclosing namespace resolves ahead of the using directive above. - private class IPCDriverConstructor : Unity.Netcode.Transports.UTP.INetworkStreamDriverConstructor + private class IPCDriverConstructor : Transports.UTP.INetworkStreamDriverConstructor { public void CreateDriver( UnityTransport transport, diff --git a/testproject/ProjectSettings/NetCodeClientAndServerSettings.asset b/testproject/ProjectSettings/NetCodeClientAndServerSettings.asset index 09eae04db5..9994ae3ddb 100644 --- a/testproject/ProjectSettings/NetCodeClientAndServerSettings.asset +++ b/testproject/ProjectSettings/NetCodeClientAndServerSettings.asset @@ -15,7 +15,7 @@ MonoBehaviour: FilterSettings: ExcludedBakingSystemAssemblies: [] AdditionalScriptingDefines: [] - GlobalNetCodeConfig: {fileID: 11400000, guid: c547acbddd81d32a0ba5e62ddfc4f4e3, type: 2} + GlobalNetcodeConfig: {fileID: 11400000, guid: c547acbddd81d32a0ba5e62ddfc4f4e3, type: 2} CurrentImportanceSuggestions: - MinValue: 1 MaxValue: 4 From fc2021dd2f2e16f60028aa03765751f20bbfe6ef Mon Sep 17 00:00:00 2001 From: Noel Stephens Date: Tue, 8 Sep 2026 12:51:40 -0500 Subject: [PATCH 3/4] chore: alias n4e's clashing driver constructor instead of qualifying it The formatter and the compiler want opposite things here. With N4E present the bare INetworkStreamDriverConstructor binds to N4E's copy in the shared Unity.Netcode root, which the enclosing namespace reaches before the using directive, and the class then fails to implement it. With N4E absent - which is what the standards job's editor resolves - any qualification is redundant and IDE0001 strips it back off, so the last two attempts each traded one failure for the other. A file-scope using alias satisfies both. Its target cannot be shortened, since at file scope there is no enclosing namespace to shorten it against; the use site is a single identifier with no qualified form; and IDE0005 cannot drop the alias because removing it stops the name resolving at all. --- .../Tests/Editor/Transports/UnityTransportTests.cs | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/com.unity.netcode.gameobjects/Tests/Editor/Transports/UnityTransportTests.cs b/com.unity.netcode.gameobjects/Tests/Editor/Transports/UnityTransportTests.cs index bf5e3f15a1..e04b3fc9f0 100644 --- a/com.unity.netcode.gameobjects/Tests/Editor/Transports/UnityTransportTests.cs +++ b/com.unity.netcode.gameobjects/Tests/Editor/Transports/UnityTransportTests.cs @@ -3,6 +3,10 @@ using Unity.Networking.Transport; using UnityEngine; using UnityEngine.TestTools; +// Netcode for Entities declares an INetworkStreamDriverConstructor of its own in the shared Unity.Netcode +// root, which the enclosing namespace resolves ahead of the import above. Aliasing it keeps this pointing +// at NGO's, and unlike a qualified name there is nothing here for the formatter to simplify away. +using UtpDriverConstructor = Unity.Netcode.Transports.UTP.INetworkStreamDriverConstructor; namespace Unity.Netcode.GameObjects.EditorTests { @@ -231,9 +235,7 @@ public void UnityTransport_HostnameValidation((string, bool) testCase) } #endif - // Qualified: Netcode for Entities declares an INetworkStreamDriverConstructor of its own in the - // Unity.Netcode root, which the enclosing namespace resolves ahead of the using directive above. - private class IPCDriverConstructor : Transports.UTP.INetworkStreamDriverConstructor + private class IPCDriverConstructor : UtpDriverConstructor { public void CreateDriver( UnityTransport transport, From 0886d47c7cea08206d4ffa897c97bab74d22f2ee Mon Sep 17 00:00:00 2001 From: Noel Stephens Date: Tue, 8 Sep 2026 15:44:41 -0500 Subject: [PATCH 4/4] chore: depend on n4e 6.7.0 and compile the unified path against either version The 7.0.0 dependency could not be satisfied anywhere. Every editor available today - 6000.7.0a6 and current trunk alike - lists com.unity.netcode 6.7.0 as mustBeBundled in its manifest, so UPM drops a 7.0.0 request silently: no assemblies, no packages-lock entry, no warning. upm-pvp then fails hard with "depends on com.unity.netcode, which is not in the lock file", which is what took out Validate on all three platforms and Package Test on both editors. Dependency versions are minimums, so asking for 6.7.0 resolves the bundled package today and picks up 7.0.0 by itself once an editor manifest carries it. The transport bump goes back to 2.6.0: 6.5.0 was never published (the 6.x line is editor-bundled only, latest published is 2.7.4), so it fails PVP-160-1, which the Validate job explicitly requires - and N4E asks for 6.5.0 itself, so resolution is unaffected either way. With the dependency resolving everywhere, nothing needs a trunk editor and validation_editors goes back to what develop had. Since either version can now be what resolves, the unified path compiles against both, gated on a UNIFIED_NETCODE_7_0_0 versionDefine keyed to the resolved package version. The 6.7.0 spellings are aliased to the 7.0.0 names so the use sites read the same either way, except N4E's Netcode class: inside namespace Unity.Netcode that name binds to the enclosing namespace before any file-scope alias is considered, so it is aliased as EntitiesNetcode in both. GhostObjectScaleExtensions is 7.0.0-only, since 6.7.0 still has the method it stands in for. That also makes the dependency real rather than dropped, which has consequences worth knowing: N4E's assemblies now build in every project, its ClientServerBootstrap becomes the Entities bootstrap with a non-zero AutoConnectPort, and it writes a NetcodeConfig into the project when its settings asset does not resolve one - which is why the GlobalNetCodeConfig field goes back to the 6.7.0 spelling here. Verified on 6000.7.0a6 against both versions: shipping (unified off), unified against bundled 6.7.0, and unified against 7.0.0 all compile with zero errors, and the standards check is clean. --- .yamato/project.metafile | 9 +-------- com.unity.netcode.gameobjects/CHANGELOG.md | 4 +--- .../Editor/NetworkObjectEditor.cs | 5 +++++ .../Editor/Unity.Netcode.Editor.asmdef | 5 +++++ .../Components/Helpers/NetworkObjectBridge.cs | 12 +++++++++--- .../Components/Helpers/UnifiedBootstrap.cs | 3 +++ .../Helpers/UnifiedUpdateConnections.cs | 3 +++ .../Runtime/Core/NetworkManager.cs | 15 +++++++++++++-- .../Runtime/Core/NetworkObject.cs | 3 ++- .../Runtime/Spawning/NetworkPrefabHandler.cs | 3 ++- .../Unified/UnifiedNetcodeTransport.cs | 4 ++++ .../Runtime/Unity.Netcode.Runtime.asmdef | 5 +++++ .../TestHelpers/NetcodeIntegrationTest.cs | 18 +++++++++++++----- .../Runtime/Unity.Netcode.Runtime.Tests.asmdef | 5 +++++ com.unity.netcode.gameobjects/package.json | 4 ++-- .../NetCodeClientAndServerSettings.asset | 2 +- 16 files changed, 74 insertions(+), 26 deletions(-) diff --git a/.yamato/project.metafile b/.yamato/project.metafile index 8f5417cea8..8c5b02077d 100644 --- a/.yamato/project.metafile +++ b/.yamato/project.metafile @@ -175,16 +175,9 @@ test_platforms: # Editors to be used for testing. NGOv3.X official support started from 6000.7 editor # TODO: When a new editor will be released it should be added to this list -# TEMPORARY: only trunk has dropped Netcode for Entities as a core package, so only there does the -# com.unity.netcode 7.0.0 dependency resolve. A released editor bundles 6.7.0 as a built-in package and -# UPM then drops the 7.0.0 request silently, leaving N4E out of the project entirely - which still -# compiles, since the unified API is opt-in. `default` runs the jobs that should see N4E present. -# `minimal` stays on a released editor: it is what the standards job opens the project with, and trunk -# rewrites ProjectVersion.txt out from under the cleanliness check. Restore `default` once a released -# editor ships without N4E as a core package; `all` is left alone as the reminder. validation_editors: default: - - trunk + - 6000.7 all: - 6000.7.0a6 - 6000.7 diff --git a/com.unity.netcode.gameobjects/CHANGELOG.md b/com.unity.netcode.gameobjects/CHANGELOG.md index 683130dd33..7fe9f6fdc7 100644 --- a/com.unity.netcode.gameobjects/CHANGELOG.md +++ b/com.unity.netcode.gameobjects/CHANGELOG.md @@ -10,12 +10,10 @@ Additional documentation and release notes are available at [Multiplayer Documen ### Added -- Netcode for Entities (`com.unity.netcode` 7.0.0) is now a dependency, so installing Netcode for GameObjects also brings it, and its own dependencies (Entities, Burst, Collections), into the project. +- Netcode for Entities (`com.unity.netcode` 6.7.0) is now a dependency, so installing Netcode for GameObjects also brings it, and its own dependencies (Entities, Burst, Collections), into the project. ### Changed -- The `com.unity.transport` dependency moved from 2.6.0 to 6.5.0, the version Netcode for Entities 7.0.0 requires. - - Changed `NetworkTransform.UseHalfFloatPrecision` to synchronize position with a resolution of approximately 1mm regardless of how far an object has travelled. Previously the resolution could degrade to approximately 3cm. This does not increase bandwidth, but projects using `NetworkTransform.UseUnreliableDeltas` will send full precision position updates more often. (#4129) - All editor assembly definitions are renamed with `Unity.Netcode.GameObjects.x` variants diff --git a/com.unity.netcode.gameobjects/Editor/NetworkObjectEditor.cs b/com.unity.netcode.gameobjects/Editor/NetworkObjectEditor.cs index 312e875850..f6c57c8b61 100644 --- a/com.unity.netcode.gameobjects/Editor/NetworkObjectEditor.cs +++ b/com.unity.netcode.gameobjects/Editor/NetworkObjectEditor.cs @@ -1,6 +1,11 @@ using System.Collections.Generic; #if UNIFIED_NETCODE +#if UNIFIED_NETCODE_7_0_0 using Unity.Netcode.Editor; +#else +using Unity.NetCode; +using Unity.NetCode.Editor; +#endif #endif using UnityEditor; using UnityEngine; diff --git a/com.unity.netcode.gameobjects/Editor/Unity.Netcode.Editor.asmdef b/com.unity.netcode.gameobjects/Editor/Unity.Netcode.Editor.asmdef index 36c3483abc..381763e3c6 100644 --- a/com.unity.netcode.gameobjects/Editor/Unity.Netcode.Editor.asmdef +++ b/com.unity.netcode.gameobjects/Editor/Unity.Netcode.Editor.asmdef @@ -21,6 +21,11 @@ "autoReferenced": true, "defineConstraints": [], "versionDefines": [ + { + "name": "com.unity.netcode", + "expression": "7.0.0", + "define": "UNIFIED_NETCODE_7_0_0" + }, { "name": "com.unity.multiplayer.tools", "expression": "", diff --git a/com.unity.netcode.gameobjects/Runtime/Components/Helpers/NetworkObjectBridge.cs b/com.unity.netcode.gameobjects/Runtime/Components/Helpers/NetworkObjectBridge.cs index 2eb69c88fb..07818501c5 100644 --- a/com.unity.netcode.gameobjects/Runtime/Components/Helpers/NetworkObjectBridge.cs +++ b/com.unity.netcode.gameobjects/Runtime/Components/Helpers/NetworkObjectBridge.cs @@ -1,5 +1,8 @@ #if UNIFIED_NETCODE using Unity.Mathematics; +#if !UNIFIED_NETCODE_7_0_0 +using Unity.NetCode; +#endif using Unity.Transforms; using UnityEngine; @@ -87,10 +90,12 @@ internal void ApplyScale(Vector3 scale) } } +#if UNIFIED_NETCODE_7_0_0 /// - /// Stands in for N4E's GhostObject.ApplyPostTransformMatrixScale, removed by the 6.7.0 non-uniform - /// scale rework that gave the GameObject-to-entity transform sync ownership of the - /// . Remove this once N4E exposes a supported way to push scale to a ghost. + /// Stands in for N4E's GhostObject.ApplyPostTransformMatrixScale, which 7.0.0 removed along with the + /// non-uniform scale rework that gave the GameObject-to-entity transform sync ownership of the + /// . 6.7.0 still has the method, so this is only compiled against 7.0.0. + /// Remove it once N4E exposes a supported way to push scale to a ghost. /// internal static class GhostObjectScaleExtensions { @@ -123,5 +128,6 @@ internal static void ApplyPostTransformMatrixScale(this GhostObject ghost, Vecto entityManager.SetComponentData(entity, localTransform); } } +#endif } #endif diff --git a/com.unity.netcode.gameobjects/Runtime/Components/Helpers/UnifiedBootstrap.cs b/com.unity.netcode.gameobjects/Runtime/Components/Helpers/UnifiedBootstrap.cs index 8c9167de54..3a41f7b3a9 100644 --- a/com.unity.netcode.gameobjects/Runtime/Components/Helpers/UnifiedBootstrap.cs +++ b/com.unity.netcode.gameobjects/Runtime/Components/Helpers/UnifiedBootstrap.cs @@ -4,6 +4,9 @@ #if UNIFIED_NETCODE using System; using Unity.Entities; +#if !UNIFIED_NETCODE_7_0_0 +using Unity.NetCode; +#endif using UnityEngine; namespace Unity.Netcode diff --git a/com.unity.netcode.gameobjects/Runtime/Components/Helpers/UnifiedUpdateConnections.cs b/com.unity.netcode.gameobjects/Runtime/Components/Helpers/UnifiedUpdateConnections.cs index 513f84cfc7..db3988b0fd 100644 --- a/com.unity.netcode.gameobjects/Runtime/Components/Helpers/UnifiedUpdateConnections.cs +++ b/com.unity.netcode.gameobjects/Runtime/Components/Helpers/UnifiedUpdateConnections.cs @@ -2,6 +2,9 @@ using System.Collections.Generic; using Unity.Collections; using Unity.Entities; +#if !UNIFIED_NETCODE_7_0_0 +using Unity.NetCode; +#endif using UnityEngine; namespace Unity.Netcode.Components diff --git a/com.unity.netcode.gameobjects/Runtime/Core/NetworkManager.cs b/com.unity.netcode.gameobjects/Runtime/Core/NetworkManager.cs index c21af7dd39..185d682f66 100644 --- a/com.unity.netcode.gameobjects/Runtime/Core/NetworkManager.cs +++ b/com.unity.netcode.gameobjects/Runtime/Core/NetworkManager.cs @@ -4,6 +4,17 @@ using Unity.Collections; #if UNIFIED_NETCODE using Unity.Entities; +// N4E's own Netcode class cannot be aliased as "Netcode": inside namespace Unity.Netcode that name +// resolves to the enclosing Unity.Netcode namespace before any file-scope alias is considered, so it gets +// its own name here. 6.7.0 additionally keeps the config and world types under the older Unity.NetCode +// casing, aliased to the 7.0.0 spellings so the use sites below read the same either way. +#if UNIFIED_NETCODE_7_0_0 +using EntitiesNetcode = Unity.Netcode.Netcode; +#else +using EntitiesNetcode = Unity.NetCode.Netcode; +using NetcodeConfig = Unity.NetCode.NetCodeConfig; +using NetcodeWorld = Unity.NetCode.NetcodeWorld; +#endif #endif using Unity.Netcode.Components; using Unity.Netcode.GameObjects.Timing; @@ -1370,13 +1381,13 @@ internal void InitializeNetcodeWorld() if (this == Singleton) { - if (Netcode.IsActive) + if (EntitiesNetcode.IsActive) { Log.Info(new Context(LogLevel.Normal, "Netcode is not active but has an instance at this point.")); } /// !! Important !! /// Clear out any pre-existing configuration in the event this applicatioin instance has already been connected to a session. - Netcode.Reset(); + EntitiesNetcode.Reset(); } /// !! Initialize worlds here !! diff --git a/com.unity.netcode.gameobjects/Runtime/Core/NetworkObject.cs b/com.unity.netcode.gameobjects/Runtime/Core/NetworkObject.cs index 8d893a78f0..0b39c84f6f 100644 --- a/com.unity.netcode.gameobjects/Runtime/Core/NetworkObject.cs +++ b/com.unity.netcode.gameobjects/Runtime/Core/NetworkObject.cs @@ -7,7 +7,8 @@ using Unity.Netcode.Components; using Unity.Netcode.Logging; using Unity.Netcode.Runtime; -#if UNIFIED_NETCODE +#if UNIFIED_NETCODE && !UNIFIED_NETCODE_7_0_0 +using Unity.NetCode; #endif #if UNITY_EDITOR diff --git a/com.unity.netcode.gameobjects/Runtime/Spawning/NetworkPrefabHandler.cs b/com.unity.netcode.gameobjects/Runtime/Spawning/NetworkPrefabHandler.cs index e4c69bfdad..daf8d153c0 100644 --- a/com.unity.netcode.gameobjects/Runtime/Spawning/NetworkPrefabHandler.cs +++ b/com.unity.netcode.gameobjects/Runtime/Spawning/NetworkPrefabHandler.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; -#if UNIFIED_NETCODE +#if UNIFIED_NETCODE && !UNIFIED_NETCODE_7_0_0 +using Unity.NetCode; #endif using UnityEngine; diff --git a/com.unity.netcode.gameobjects/Runtime/Transports/Unified/UnifiedNetcodeTransport.cs b/com.unity.netcode.gameobjects/Runtime/Transports/Unified/UnifiedNetcodeTransport.cs index b8509f4ea6..de23142229 100644 --- a/com.unity.netcode.gameobjects/Runtime/Transports/Unified/UnifiedNetcodeTransport.cs +++ b/com.unity.netcode.gameobjects/Runtime/Transports/Unified/UnifiedNetcodeTransport.cs @@ -6,6 +6,10 @@ using Unity.Collections; using Unity.Collections.LowLevel.Unsafe; using Unity.Entities; +#if !UNIFIED_NETCODE_7_0_0 +using Unity.NetCode; +using NetcodeConnectionEvent = Unity.NetCode.NetCodeConnectionEvent; +#endif using Unity.Netcode.GameObjects.Timing; using Unity.Netcode.Transports.UTP; using UnityEngine; diff --git a/com.unity.netcode.gameobjects/Runtime/Unity.Netcode.Runtime.asmdef b/com.unity.netcode.gameobjects/Runtime/Unity.Netcode.Runtime.asmdef index e5d50997cc..847c5494ed 100644 --- a/com.unity.netcode.gameobjects/Runtime/Unity.Netcode.Runtime.asmdef +++ b/com.unity.netcode.gameobjects/Runtime/Unity.Netcode.Runtime.asmdef @@ -26,6 +26,11 @@ "autoReferenced": true, "defineConstraints": [], "versionDefines": [ + { + "name": "com.unity.netcode", + "expression": "7.0.0", + "define": "UNIFIED_NETCODE_7_0_0" + }, { "name": "com.unity.multiplayer.tools", "expression": "", diff --git a/com.unity.netcode.gameobjects/Tests/Runtime/TestHelpers/NetcodeIntegrationTest.cs b/com.unity.netcode.gameobjects/Tests/Runtime/TestHelpers/NetcodeIntegrationTest.cs index 18ea591472..9a43f33eea 100644 --- a/com.unity.netcode.gameobjects/Tests/Runtime/TestHelpers/NetcodeIntegrationTest.cs +++ b/com.unity.netcode.gameobjects/Tests/Runtime/TestHelpers/NetcodeIntegrationTest.cs @@ -6,6 +6,14 @@ using System.Runtime.CompilerServices; using System.Text; using NUnit.Framework; +#if UNIFIED_NETCODE +#if UNIFIED_NETCODE_7_0_0 +using EntitiesNetcode = Unity.Netcode.Netcode; +#else +using Unity.NetCode; +using EntitiesNetcode = Unity.NetCode.Netcode; +#endif +#endif using Unity.Netcode.GameObjects.Timing; using Unity.Netcode.RuntimeTests; using Unity.Netcode.Transports.UTP; @@ -2648,11 +2656,11 @@ internal void SpawnInstanceWithOwnership(NetworkObject networkObjectToSpawn, Net else { #if UNIFIED_NETCODE - // TODO-FixMe: Netcode.Instance is a singleton and might cause issues + // TODO-FixMe: the Netcode instance is a singleton and might cause issues // assigning this. if (networkObjectToSpawn.HasGhost) { - Netcode.Instance.m_ActiveWorld = m_ServerNetworkManager.NetcodeWorld; + EntitiesNetcode.Instance.m_ActiveWorld = m_ServerNetworkManager.NetcodeWorld; } #endif networkObjectToSpawn.NetworkManagerOwner = m_ServerNetworkManager; // Required to assure the server does the spawning @@ -2716,14 +2724,14 @@ private GameObject SpawnObject(NetworkObject prefabNetworkObject, NetworkManager // This has to happen *before* Instantiate, not after. The hybrid prefab is active, so the clone's // GhostObject.Awake runs synchronously inside Object.Instantiate below. The clone is not a prefab // (its prefabReference.Prefab points at the prefab, not at itself), so Awake acquires an entity - // reference, which resolves the world to spawn into from the Netcode.Instance.m_ActiveWorld singleton. + // reference, which resolves the world to spawn into from the EntitiesNetcode.Instance.m_ActiveWorld singleton. // N4E's rate managers reassign that singleton on every world update, so by the time a test body runs // it points at whichever world updated last - typically a client world - and the spawn is rejected with // "You can only spawn a ghost on a server or during prediction on a client." - // TODO-UNIFIED: Netcode.Instance is a singleton and might cause issues assigning this. + // TODO-UNIFIED: the Netcode instance is a singleton and might cause issues assigning this. if (prefabNetworkObject.HasGhost) { - Netcode.Instance.m_ActiveWorld = m_ServerNetworkManager.NetcodeWorld; + EntitiesNetcode.Instance.m_ActiveWorld = m_ServerNetworkManager.NetcodeWorld; } #endif var newInstance = Object.Instantiate(prefabNetworkObject.gameObject); diff --git a/com.unity.netcode.gameobjects/Tests/Runtime/Unity.Netcode.Runtime.Tests.asmdef b/com.unity.netcode.gameobjects/Tests/Runtime/Unity.Netcode.Runtime.Tests.asmdef index d620159256..0bb1905817 100644 --- a/com.unity.netcode.gameobjects/Tests/Runtime/Unity.Netcode.Runtime.Tests.asmdef +++ b/com.unity.netcode.gameobjects/Tests/Runtime/Unity.Netcode.Runtime.Tests.asmdef @@ -30,6 +30,11 @@ "UNITY_INCLUDE_TESTS" ], "versionDefines": [ + { + "name": "com.unity.netcode", + "expression": "7.0.0", + "define": "UNIFIED_NETCODE_7_0_0" + }, { "name": "com.unity.multiplayer.tools", "expression": "", diff --git a/com.unity.netcode.gameobjects/package.json b/com.unity.netcode.gameobjects/package.json index 4c081beac9..5b281ba50f 100644 --- a/com.unity.netcode.gameobjects/package.json +++ b/com.unity.netcode.gameobjects/package.json @@ -7,8 +7,8 @@ "unityRelease": "0a6", "dependencies": { "com.unity.nuget.mono-cecil": "1.11.4", - "com.unity.transport": "6.5.0", - "com.unity.netcode": "7.0.0" + "com.unity.transport": "2.6.0", + "com.unity.netcode": "6.7.0" }, "samples": [ { diff --git a/testproject/ProjectSettings/NetCodeClientAndServerSettings.asset b/testproject/ProjectSettings/NetCodeClientAndServerSettings.asset index 9994ae3ddb..09eae04db5 100644 --- a/testproject/ProjectSettings/NetCodeClientAndServerSettings.asset +++ b/testproject/ProjectSettings/NetCodeClientAndServerSettings.asset @@ -15,7 +15,7 @@ MonoBehaviour: FilterSettings: ExcludedBakingSystemAssemblies: [] AdditionalScriptingDefines: [] - GlobalNetcodeConfig: {fileID: 11400000, guid: c547acbddd81d32a0ba5e62ddfc4f4e3, type: 2} + GlobalNetCodeConfig: {fileID: 11400000, guid: c547acbddd81d32a0ba5e62ddfc4f4e3, type: 2} CurrentImportanceSuggestions: - MinValue: 1 MaxValue: 4