Skip to content

Commit b7327c9

Browse files
chore: netcode for entities 7.0.0 as a dependency (#4158)
* 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. * 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. * 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. * 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. * Update com.unity.netcode.gameobjects/CHANGELOG.md * Updated editor used after 0b1 got released and package dependencies * Updated testproject and minimalproject to 6000.7.0b1 * Fix for CI issues (will file a ticket) * correction of previous fix * re-added services.multiplayer package as compatible version was released * Disabled tests * reverted re-adding of services as that version is still not compatible with N4E --------- Co-authored-by: Michał Chrobot <124174716+michalChrobot@users.noreply.github.com> Co-authored-by: Michał Chrobot <michal.chrobot@unity3d.com>
1 parent 9fda16e commit b7327c9

38 files changed

Lines changed: 219 additions & 121 deletions

‎.yamato/_triggers.yml‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,8 @@ pr_code_changes_checks:
9090
# Note that our daily tests will anyway run both test configurations in "minimal supported" and "trunk" configurations
9191
- .yamato/desktop-standalone-tests.yml#desktop_standalone_test_testproject_ubuntu_il2cpp_{{ pinnedTrunk }}
9292
- .yamato/cmb-service-standalone-tests.yml#cmb_service_standalone_test_testproject_ubuntu_il2cpp_{{ pinnedTrunk }}
93-
- .yamato/_run-all.yml#run_all_unified_tests
93+
# The unified (NGO + N4E) tests are no longer a PR check: the unified API is behind N4E's own
94+
# experimental define, so it is not part of what NGO ships. Still run nightly and on "/ci unified".
9495
# Run code coverage test (PRs use the pinned "safe" trunk)
9596
- .yamato/code-coverage.yml#code_coverage_project_test_testproject_ubuntu_{{ pinnedTrunk }}
9697
triggers:

‎.yamato/project.metafile‎

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -179,13 +179,13 @@ validation_editors:
179179
default:
180180
- 6000.7
181181
all:
182-
- 6000.7.0a6
182+
- 6000.7.0b1
183183
- 6000.7
184184
- trunk
185-
- 1d47644d0e359a8139ae6f99217da3c4e47f4779
185+
- dfdad7ed5522da345003b66ed78dc5e725357037
186186
minimal:
187-
- 6000.7.0a6
188-
pinnedTrunk: 1d47644d0e359a8139ae6f99217da3c4e47f4779
187+
- 6000.7.0b1
188+
pinnedTrunk: dfdad7ed5522da345003b66ed78dc5e725357037
189189

190190

191191
# Scripting backends used by Standalone RunTimeTests---------------------------------------------------

‎.yamato/unified-tests.yml‎

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,10 @@
1010
# 2. For all unified editors (currently a single pinned alpha, see project.metafile)
1111

1212
# QUALITY CONSIDERATIONS--------------------------------------------------------------------
13-
# TODO: the manifest swap means testproject/Packages/manifest-unified.json has to be kept in sync
14-
# with manifest.json by hand. Revisit once N4E is a hard dependency of NGO and one manifest
15-
# can cover both cases.
13+
# TODO: N4E is now a hard dependency, so the manifest swap only pins the N4E version and the two
14+
# manifests can be collapsed into one.
15+
# This job is deliberately not part of the PR checks: N4E 7.0.0 ships the unified API behind its own
16+
# experimental define, so nothing in the shipping configuration compiles it.
1617

1718
#------------------------------------------------------------------------------------
1819

@@ -36,9 +37,11 @@ unified_test_{{ project.name }}_{{ platform.name }}_{{ editor }}:
3637
UNIFIED_TESTS: "true"
3738

3839
commands:
39-
# Swap in the manifest that has the unified packages and versions required.
40-
# Without the N4E package, UNIFIED_NETCODE is undefined and the unified API excluded.
40+
# Swap in the manifest that pins the N4E version the unified API is written against.
4141
- cp {{ project.path }}/Packages/manifest-unified.json {{ project.path }}/Packages/manifest.json
42+
# Turn the unified API on. UNIFIED_NETCODE is opt-in, and N4E keeps its GameObject bridge internal
43+
# until NETCODE_GAMEOBJECT_BRIDGE_EXPERIMENTAL is defined, so both are needed here and nowhere else.
44+
- 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
4245
- unity-downloader-cli --fast --wait -u {{ editor }} -c Editor
4346
- 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 }}
4447
artifacts:

‎com.unity.netcode.gameobjects/CHANGELOG.md‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ Additional documentation and release notes are available at [Multiplayer Documen
1010

1111
### Added
1212

13+
- Netcode for Entities (`com.unity.netcode` 7.0.0) is now a hard dependency, so installing Netcode for GameObjects also brings it, and its own dependencies (Entities, Burst, Collections), into the project.
14+
1315
### Changed
1416

1517
- 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)

‎com.unity.netcode.gameobjects/Editor/NetworkObjectEditor.cs‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,12 @@
11
using System.Collections.Generic;
22
#if UNIFIED_NETCODE
3+
#if UNIFIED_NETCODE_7_0_0
4+
using Unity.Netcode.Editor;
5+
#else
36
using Unity.NetCode;
47
using Unity.NetCode.Editor;
58
#endif
9+
#endif
610
using UnityEditor;
711
using UnityEngine;
812
using UnityEngine.Scripting.APIUpdating;

‎com.unity.netcode.gameobjects/Editor/Unity.Netcode.Editor.asmdef‎

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,11 @@
2121
"autoReferenced": true,
2222
"defineConstraints": [],
2323
"versionDefines": [
24+
{
25+
"name": "com.unity.netcode",
26+
"expression": "7.0.0",
27+
"define": "UNIFIED_NETCODE_7_0_0"
28+
},
2429
{
2530
"name": "com.unity.multiplayer.tools",
2631
"expression": "",
@@ -46,11 +51,6 @@
4651
"expression": "0.2.0",
4752
"define": "MULTIPLAYER_SERVICES_SDK_INSTALLED"
4853
},
49-
{
50-
"name": "com.unity.netcode",
51-
"expression": "1.10.1",
52-
"define": "UNIFIED_NETCODE"
53-
},
5454
{
5555
"name": "com.unity.multiplayer.playmode",
5656
"expression": "0.1.0",

‎com.unity.netcode.gameobjects/Runtime/Components/AnticipatedNetworkTransform.cs‎

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,13 +21,13 @@ namespace Unity.Netcode.Components
2121
/// resulting in a "snap" to the new value if it is different from the anticipated value.</description></item>
2222
///
2323
/// <item><description><b>Smooth:</b> In this mode (with <see cref="StaleDataHandling"/> set to
24-
/// <see cref="Netcode.StaleDataHandling.Ignore"/> and an <see cref="NetworkBehaviour.OnReanticipate"/> callback that calls
24+
/// <see cref="StaleDataHandling.Ignore"/> and an <see cref="NetworkBehaviour.OnReanticipate"/> callback that calls
2525
/// <see cref="Smooth"/> from the anticipated value to the authority value with an appropriate
2626
/// <see cref="Mathf.Lerp"/>-style smooth function), when a more up-to-date value is received from the authority,
2727
/// it will interpolate over time from an incorrect anticipated value to the correct authoritative value.</description></item>
2828
///
2929
/// <item><description><b>Constant Reanticipation:</b> In this mode (with <see cref="StaleDataHandling"/> set to
30-
/// <see cref="Netcode.StaleDataHandling.Reanticipate"/> and an <see cref="NetworkBehaviour.OnReanticipate"/> that calculates a
30+
/// <see cref="StaleDataHandling.Reanticipate"/> and an <see cref="NetworkBehaviour.OnReanticipate"/> that calculates a
3131
/// new anticipated value based on the current authoritative value), when a more up-to-date value is received from
3232
/// the authority, user code calculates a new anticipated value, possibly calling <see cref="Smooth"/> to interpolate
3333
/// between the previous anticipation and the new anticipation. This is useful for values that change frequently and
@@ -101,11 +101,11 @@ private void Reset()
101101
/// Defines what the behavior should be if we receive a value from the server with an earlier associated
102102
/// time value than the anticipation time value.
103103
/// <br/><br/>
104-
/// If this is <see cref="Netcode.StaleDataHandling.Ignore"/>, the stale data will be ignored and the authoritative
104+
/// If this is <see cref="StaleDataHandling.Ignore"/>, the stale data will be ignored and the authoritative
105105
/// value will not replace the anticipated value until the anticipation time is reached. <see cref="OnAuthoritativeValueChanged"/>
106106
/// and <see cref="OnReanticipate"/> will also not be invoked for this stale data.
107107
/// <br/><br/>
108-
/// If this is <see cref="Netcode.StaleDataHandling.Reanticipate"/>, the stale data will replace the anticipated data and
108+
/// If this is <see cref="StaleDataHandling.Reanticipate"/>, the stale data will replace the anticipated data and
109109
/// <see cref="OnAuthoritativeValueChanged"/> and <see cref="OnReanticipate"/> will be invoked.
110110
/// In this case, the authoritativeTime value passed to <see cref="OnReanticipate"/> will be lower than
111111
/// the anticipationTime value, and that callback can be used to calculate a new anticipated value.

‎com.unity.netcode.gameobjects/Runtime/Components/Helpers/NetworkObjectBridge.cs‎

Lines changed: 47 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
#if UNIFIED_NETCODE
2+
using Unity.Mathematics;
3+
#if !UNIFIED_NETCODE_7_0_0
24
using Unity.NetCode;
5+
#endif
6+
using Unity.Transforms;
37
using UnityEngine;
48

59
namespace Unity.Netcode
@@ -13,7 +17,9 @@ namespace Unity.Netcode
1317

1418
[DefaultExecutionOrder(GhostObject.ExecutionOrder + 1)]
1519
//BREAK --- Fix this on UNIFIED side 1st
16-
public partial class NetworkObjectBridge : GhostBehaviour
20+
// Internal: GhostBehaviour is only public when NETCODE_GAMEOBJECT_BRIDGE_EXPERIMENTAL is defined, and a public
21+
// type cannot derive from an internal one.
22+
internal partial class NetworkObjectBridge : GhostBehaviour
1723
{
1824
// DefaultExecutionOrder
1925
// TODO: Define a const for the value used on GhostObject and use that value
@@ -83,5 +89,45 @@ internal void ApplyScale(Vector3 scale)
8389
Ghost.ApplyPostTransformMatrixScale(scale);
8490
}
8591
}
92+
93+
#if UNIFIED_NETCODE_7_0_0
94+
/// <summary>
95+
/// Stands in for N4E's <c>GhostObject.ApplyPostTransformMatrixScale</c>, which 7.0.0 removed along with the
96+
/// non-uniform scale rework that gave the GameObject-to-entity transform sync ownership of the
97+
/// <see cref="PostTransformMatrix"/>. 6.7.0 still has the method, so this is only compiled against 7.0.0.
98+
/// Remove it once N4E exposes a supported way to push scale to a ghost.
99+
/// </summary>
100+
internal static class GhostObjectScaleExtensions
101+
{
102+
/// <summary>
103+
/// A ghost that replicates 3D scale stores it in its <see cref="PostTransformMatrix"/> and holds
104+
/// <see cref="LocalTransform.Scale"/> at 1, because consumers multiply the two. A ghost authored with
105+
/// <c>UseUniformScale</c> has no matrix - and cannot gain one at runtime, since the component is only in the
106+
/// replicated set when the prefab is registered - so only the uniform scale can be applied there.
107+
/// </summary>
108+
internal static void ApplyPostTransformMatrixScale(this GhostObject ghost, Vector3 scale)
109+
{
110+
var entityManager = ghost.World.EntityManager;
111+
var entity = ghost.Entity;
112+
var localTransform = entityManager.GetComponentData<LocalTransform>(entity);
113+
114+
if (entityManager.HasComponent<PostTransformMatrix>(entity))
115+
{
116+
entityManager.SetComponentData(entity, new PostTransformMatrix { Value = float4x4.Scale(scale) });
117+
localTransform.Scale = 1f;
118+
}
119+
else
120+
{
121+
if (!Mathf.Approximately(scale.x, scale.y) || !Mathf.Approximately(scale.y, scale.z))
122+
{
123+
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);
124+
}
125+
localTransform.Scale = scale.x;
126+
}
127+
128+
entityManager.SetComponentData(entity, localTransform);
129+
}
130+
}
131+
#endif
86132
}
87133
#endif

‎com.unity.netcode.gameobjects/Runtime/Components/Helpers/UnifiedBootstrap.cs‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,12 @@
1+
#if UNIFIED_NETCODE && !NETCODE_GAMEOBJECT_BRIDGE_EXPERIMENTAL
2+
#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.
3+
#endif
14
#if UNIFIED_NETCODE
25
using System;
36
using Unity.Entities;
7+
#if !UNIFIED_NETCODE_7_0_0
48
using Unity.NetCode;
9+
#endif
510
using UnityEngine;
611

712
namespace Unity.Netcode

‎com.unity.netcode.gameobjects/Runtime/Components/Helpers/UnifiedUpdateConnections.cs‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,9 @@
22
using System.Collections.Generic;
33
using Unity.Collections;
44
using Unity.Entities;
5+
#if !UNIFIED_NETCODE_7_0_0
56
using Unity.NetCode;
7+
#endif
68
using UnityEngine;
79

810
namespace Unity.Netcode.Components

0 commit comments

Comments
 (0)