Skip to content

Commit 6752d38

Browse files
chore: enable unified netcode from N4E 7.2.0, only for hybrid prefab sessions (#4186)
* chore: drop N4E experimental bridge define and OUT_OF_BAND_RPC N4E is removing NETCODE_GAMEOBJECT_BRIDGE_EXPERIMENTAL and making its GameObject layer public, so UNIFIED_NETCODE is now the only define the unified path needs. testproject takes N4E from unity/unity trunk until that change ships in a package, which makes manifest-unified.json redundant. * Enable the unified path from N4E 7.2.0 and only for hybrid prefab sessions UNIFIED_NETCODE is now an asmdef versionDefine on com.unity.netcode 7.2.0, the release that makes the GameObject layer public, so no project define is needed. UNIFIED_NETCODE_7_0_0 is gone since every supported N4E uses the new namespace. UnifiedBootstrap is marked DisableBootstrapOverrides and created by NetworkManager only when the session has hybrid prefabs, so projects without them keep N4E's own startup bootstrap. A hybrid prefab added after a session started without one is rejected. testproject takes N4E from the remove-experimental-define branch until that PR merges. * Register the player prefab before the session decides hybrid mode A hybrid PlayerPrefab outside the prefab lists was registered after the transport choice and the session-start rejection, so it was rejected. It now registers with the prefab lists before start, and distributed authority rejects it like any other hybrid prefab. * style: format unified netcode code now that UNIFIED_NETCODE compiles in testproject UNIFIED_NETCODE is now defined automatically from N4E 7.2.0, so the Standards check formats code behind it for the first time. * style: format the hybrid code merged from develop-3.x.x Keeps an implicit bool check where null propagation would call into a destroyed NetworkBehaviour. * chore: stop tracking the NetcodeConfig assets in testproject and minimalproject NGO now applies the NetcodeConfig values it needs at session start, so nothing in either asset is required. Netcode for Entities creates the asset and its project settings entry on first open. The settings file is removed too, since keeping it tracked would make every fresh checkout rewrite it. * chore: ignore the NetcodeConfig assets Netcode for Entities creates on first open The assets are no longer tracked, so the files N4E writes when a project opens would otherwise show up as untracked changes and could be committed back. * fix: keep Unity's destroyed-object check where the formatter used null propagation Implicit bool checks instead of ?. on NetworkTransform and NetworkManager, which the Standards formatter does not rewrite. * fix: keep UnifiedBootstrap as the Entities startup bootstrap [DisableBootstrapOverrides] let Netcode for Entities' own bootstrap run at startup. Without a NetcodeConfig that disables automatic bootstrapping, it creates a host world listening on port 7979, so a hybrid host could not bind the port and the unified tests failed. As the startup bootstrap, UnifiedBootstrap only creates a local world, which is how #4144 resolved this. * chore: point the Netcode for Entities git dependency at trunk The GameObject layer change has merged to trunk, so testproject follows trunk instead of the pull request branch, and minimalproject gets the same entry so both compile against N4E 7.2.0. These switch to the published 7.2.0 package once it is available.
1 parent f9d4fa8 commit 6752d38

35 files changed

Lines changed: 132 additions & 421 deletions

‎.yamato/unified-tests.yml‎

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

1212
# QUALITY CONSIDERATIONS--------------------------------------------------------------------
13-
# manifest-unified.json takes N4E from unity/unity trunk, so this job can break on N4E changes made outside NGO.
13+
# testproject takes N4E from unity/unity trunk, so this job can break on N4E changes made outside NGO.
1414

1515
#------------------------------------------------------------------------------------
1616

@@ -34,11 +34,6 @@ unified_test_{{ project.name }}_{{ platform.name }}_{{ editor }}:
3434
UNIFIED_TESTS: "true"
3535

3636
commands:
37-
# Swap in the manifest that takes N4E from unity/unity trunk Workspace/com.unity.netcode.
38-
- cp {{ project.path }}/Packages/manifest-unified.json {{ project.path }}/Packages/manifest.json
39-
# Turn the unified API on. UNIFIED_NETCODE is opt-in, and N4E keeps its GameObject bridge internal
40-
# until NETCODE_GAMEOBJECT_BRIDGE_EXPERIMENTAL is defined, so both are needed here and nowhere else.
41-
- 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
4237
- unity-downloader-cli --fast --wait -u {{ editor }} -c Editor --arch {{ platform.architecture }}
4338
- 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 }}
4439
artifacts:

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

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,6 @@
11
using System.Collections.Generic;
22
#if UNIFIED_NETCODE
3-
#if UNIFIED_NETCODE_7_0_0
43
using Unity.Netcode.Editor;
5-
#else
6-
using Unity.NetCode;
7-
using Unity.NetCode.Editor;
8-
#endif
94
#endif
105
using UnityEditor;
116
using UnityEngine;

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,8 @@
2323
"versionDefines": [
2424
{
2525
"name": "com.unity.netcode",
26-
"expression": "7.0.0",
27-
"define": "UNIFIED_NETCODE_7_0_0"
26+
"expression": "7.2.0",
27+
"define": "UNIFIED_NETCODE"
2828
},
2929
{
3030
"name": "com.unity.multiplayer.tools",

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

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,5 @@
11
#if UNIFIED_NETCODE
22
using Unity.Mathematics;
3-
#if !UNIFIED_NETCODE_7_0_0
4-
using Unity.NetCode;
5-
#endif
63
using Unity.Transforms;
74
using UnityEngine;
85

@@ -126,11 +123,10 @@ internal void UpdateGhostOwner(NetworkManager networkManager, ulong ownerClientI
126123
}
127124
}
128125

129-
#if UNIFIED_NETCODE_7_0_0
130126
/// <summary>
131127
/// Stands in for N4E's <c>GhostObject.ApplyPostTransformMatrixScale</c>, which 7.0.0 removed along with the
132128
/// non-uniform scale rework that gave the GameObject-to-entity transform sync ownership of the
133-
/// <see cref="PostTransformMatrix"/>. 6.7.0 still has the method, so this is only compiled against 7.0.0.
129+
/// <see cref="PostTransformMatrix"/>.
134130
/// Remove it once N4E exposes a supported way to push scale to a ghost.
135131
/// </summary>
136132
internal static class GhostObjectScaleExtensions
@@ -164,6 +160,5 @@ internal static void ApplyPostTransformMatrixScale(this GhostObject ghost, Vecto
164160
entityManager.SetComponentData(entity, localTransform);
165161
}
166162
}
167-
#endif
168163
}
169164
#endif

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

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,7 @@
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
41
#if UNIFIED_NETCODE
52
using System;
63
using System.Collections.Generic;
74
using Unity.Entities;
8-
#if !UNIFIED_NETCODE_7_0_0
9-
using Unity.NetCode;
10-
#endif
115
using UnityEngine;
126

137
namespace Unity.Netcode
@@ -17,6 +11,11 @@ namespace Unity.Netcode
1711
/// Handles the bootstrap process for both client and server in unified mode. This is used to create the world and set it on the
1812
/// NetworkManager during initialization.
1913
/// </summary>
14+
/// <remarks>
15+
/// Entities picks this as the startup bootstrap, which only creates a local world. Do not add
16+
/// [DisableBootstrapOverrides]: Netcode for Entities' own bootstrap would then run and, unless automatic
17+
/// bootstrapping is disabled, create a host world that holds the port a hybrid session listens on.
18+
/// </remarks>
2019
internal class UnifiedBootstrap : ClientServerBootstrap
2120
{
2221
public static UnifiedBootstrap Instance { get; private set; }

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

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

107
namespace Unity.Netcode.Components

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -289,7 +289,7 @@ private bool InitializeHybrid()
289289
}
290290

291291
// Clears any registration left behind by a prior Initialize call.
292-
if (NetworkTransform != null)
292+
if (NetworkTransform)
293293
{
294294
NetworkTransform.UnregisterRigidbody();
295295
}

‎com.unity.netcode.gameobjects/Runtime/Configuration/HybridNetcodeDefaults.cs‎

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,4 @@
11
#if UNIFIED_NETCODE
2-
#if !UNIFIED_NETCODE_7_0_0
3-
using NetcodeConfig = Unity.NetCode.NetCodeConfig;
4-
#endif
52

63
namespace Unity.Netcode
74
{

‎com.unity.netcode.gameobjects/Runtime/Configuration/NetworkConfig.cs‎

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -404,11 +404,13 @@ internal void InitializePrefabs()
404404

405405
#if UNIFIED_NETCODE
406406
/// <summary>
407-
/// Registers any prefab list assigned after Awake, and returns false for a distributed authority session with a hybrid prefab registered.
407+
/// Registers any prefab list assigned after Awake and the <see cref="PlayerPrefab"/>, and returns false for a distributed authority session with a hybrid prefab registered.
408408
/// </summary>
409-
internal bool InitializePrefabsForStart()
409+
internal bool InitializePrefabsForStart(NetworkPrefabHandler prefabHandler)
410410
{
411411
InitializePrefabs();
412+
// A player prefab outside the prefab lists still decides hybrid mode, so it is registered before the session starts.
413+
prefabHandler.RegisterPlayerPrefab();
412414
return NetworkTopology != NetworkTopologyTypes.DistributedAuthority || Prefabs.ValidateForDistributedAuthority();
413415
}
414416
#endif

‎com.unity.netcode.gameobjects/Runtime/Configuration/NetworkPrefabs.cs‎

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -173,7 +173,7 @@ internal void Shutdown()
173173
list.OnRemove -= RemoveTriggeredByNetworkPrefabList;
174174
}
175175
#if UNIFIED_NETCODE
176-
m_RejectGhostPrefabs = false;
176+
m_GhostPrefabRejection = null;
177177
#endif
178178
}
179179

@@ -367,18 +367,20 @@ public bool Contains(NetworkPrefab prefab)
367367

368368
#if UNIFIED_NETCODE
369369
internal const string DistributedAuthorityHybridPrefabError = "Distributed authority does not support hybrid prefabs.";
370+
internal const string HybridPrefabAfterStartError = "Hybrid prefabs must be registered before the NetworkManager starts.";
370371

371372
internal bool HasGhostPrefabs { get; private set; }
372373

373-
// Cleared in Shutdown.
374-
private bool m_RejectGhostPrefabs;
374+
// The error a hybrid prefab added during the session is rejected with, or null. Cleared in Shutdown.
375+
private string m_GhostPrefabRejection;
375376

376377
/// <summary>
377-
/// A distributed authority session rejects hybrid prefabs added while it runs.
378+
/// Hybrid mode is decided when the session starts. A distributed authority session, or one that started without
379+
/// hybrid prefabs, rejects hybrid prefabs added while it runs.
378380
/// </summary>
379381
internal void OnSessionStarting(bool distributedAuthority)
380382
{
381-
m_RejectGhostPrefabs = distributedAuthority;
383+
m_GhostPrefabRejection = distributedAuthority ? DistributedAuthorityHybridPrefabError : HasGhostPrefabs ? null : HybridPrefabAfterStartError;
382384
}
383385

384386
/// <summary>
@@ -426,9 +428,9 @@ private bool AddPrefabRegistration(NetworkPrefab networkPrefab)
426428
if (networkPrefab.HasGhost)
427429
{
428430
// Registering a hybrid prefab mid-session would switch NetworkManager into hybrid mode and stop its send queue.
429-
if (m_RejectGhostPrefabs)
431+
if (m_GhostPrefabRejection != null)
430432
{
431-
Debug.LogError($"{DistributedAuthorityHybridPrefabError} {networkPrefab.GetDebugName()} was not added.");
433+
Debug.LogError($"{m_GhostPrefabRejection} {networkPrefab.GetDebugName()} was not added.");
432434
return false;
433435
}
434436
HasGhostPrefabs = true;

0 commit comments

Comments
 (0)