Skip to content

Commit 4512b39

Browse files
chore: merge ngo and n4e with poc transport and updates (#3889)
* update Fixes for connection sequence where clients don't announce they are ready to receive snapshots until fully synchronized by NGO. Fixes for removing pending ghosts and ghost spawn data (especially when being destroyed). Fixes for NetworkSceneManager detecting pending ghosts as in-scene placed. Fixes for NetworkSpawnManager.RegisterGhostPendingSpawn trying to double process triggers and/or process triggers when it should not. * update & fixes Some adjustments to the POC Transport. Some fixes. * fix Wrapping reference to namespace that only exists when in unified mode. * update fixing spelling of UNIFIED_NETCODE * update Increasing max RPC size to 1340. Re-enabling the UnifiedBootStrap.AutoConnectPort. (N4E handles the connection) Removing the initial listen and/or connection within the UnifiedTransport (N4E handle this). Moving unified validation invocation to be after OnValidation early exit checks. * update Lowering max packet size to 1300.
1 parent 66e6483 commit 4512b39

File tree

8 files changed

+134
-141
lines changed

8 files changed

+134
-141
lines changed

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

Lines changed: 7 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -7,15 +7,17 @@ namespace Unity.Netcode
77
{
88

99
/// <summary>
10-
/// TODO-UNIFIED: Would need to be reviewed for alternate ways of handling this.
10+
/// TODO-UNIFIED: Needs further peer review and exploring alternate ways of handling this.
1111
/// </summary>
1212
/// <remarks>
1313
/// If used, we most likely would make this internal
1414
/// </remarks>
1515
public partial class NetworkObjectBridge : GhostBehaviour
1616
{
17-
public Action<ulong> NetworkObjectIdChanged;
18-
17+
/// <summary>
18+
/// This is used to link <see cref="NetworkObject.SerializedObject"/> data to
19+
/// N4E-spawned hybrid prefab instances.
20+
/// </summary>
1921
internal GhostField<ulong> NetworkObjectId = new GhostField<ulong>();
2022

2123
public void SetNetworkObjectId(ulong value)
@@ -41,7 +43,7 @@ public override bool Initialize(string defaultWorldName)
4143
{
4244
var networkManager = NetworkManager.Singleton;
4345
Instance = this;
44-
AutoConnectPort = 0;
46+
AutoConnectPort = Port;
4547
if (base.Initialize(defaultWorldName))
4648
{
4749
UnityEngine.Debug.LogError($"[{nameof(UnifiedBootStrap)}] Auto-bootstrap is enabled!!! This will break the POC!");
@@ -80,21 +82,10 @@ public override bool Initialize(string defaultWorldName)
8082

8183
return true;
8284
}
83-
84-
public static void StopClient()
85-
{
86-
ClientWorld.Dispose();
87-
ClientWorlds.Remove(ClientWorld);
88-
}
89-
90-
public static void StopServer()
91-
{
92-
ServerWorld.Dispose();
93-
ServerWorlds.Remove(ServerWorld);
94-
}
9585

9686
~UnifiedBootStrap()
9787
{
88+
World = null;
9889
Instance = null;
9990
}
10091
}

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

Lines changed: 21 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,6 @@ public struct NetcodeConnection
1313
internal Entity Entity;
1414
public int NetworkId;
1515

16-
internal float ConnectedTime;
17-
internal bool IsSynced;
18-
1916
public bool IsServer => World.IsServer();
2017
public void GoInGame()
2118
{
@@ -34,20 +31,13 @@ internal partial class UnifiedUpdateConnections : SystemBase
3431
private List<NetcodeConnection> m_TempConnections = new List<NetcodeConnection>();
3532

3633
private Dictionary<int, NetcodeConnection> m_NewConnections = new Dictionary<int, NetcodeConnection>();
37-
38-
public void MarkSync(int NetworkId)
39-
{
40-
if (m_NewConnections.TryGetValue(NetworkId, out var connection))
41-
{
42-
connection.IsSynced = true;
43-
m_NewConnections[NetworkId] = connection;
44-
}
45-
}
4634

4735
protected override void OnUpdate()
4836
{
4937
var isServer = World.IsServer();
5038
var commandBuffer = new EntityCommandBuffer(Allocator.Temp);
39+
var networkManager = NetworkManager.Singleton;
40+
5141
foreach (var (networkId, connectionState, entity) in SystemAPI.Query<NetworkId, ConnectionState>().WithNone<NetworkStreamConnection>().WithEntityAccess())
5242
{
5343
commandBuffer.RemoveComponent<ConnectionState>(entity);
@@ -60,16 +50,12 @@ protected override void OnUpdate()
6050

6151
m_TempConnections.Clear();
6252

63-
53+
// TODO: We should figure out how to associate the N4E NetworkId with the NGO ClientId
6454
foreach (var (networkId, entity) in SystemAPI.Query<NetworkId>().WithAll<NetworkStreamConnection>().WithNone<NetworkStreamInGame>().WithEntityAccess())
6555
{
66-
// TODO-Unified: For new connections, we have a delay before the N4E in-game state for the client to provide time for the NGO side of the client to synchronize.
67-
// Note: Once both are using the same transport we should be able to get the transport id and determine the NGO assigned client-id and at that point once the
68-
// client has signaled that it has synchronized (or has been sent the synchronization data) we finalize the in-game connection state (or something along those lines).
6956
if (!m_NewConnections.ContainsKey(networkId.Value))
7057
{
71-
var delayTime = 0.0f;// isServer ? 0.2f : 0.1f;
72-
var newConnection = new NetcodeConnection { World = World, Entity = entity, NetworkId = networkId.Value, ConnectedTime = UnityEngine.Time.realtimeSinceStartup + delayTime, IsSynced = isServer};
58+
var newConnection = new NetcodeConnection { World = World, Entity = entity, NetworkId = networkId.Value };
7359
m_NewConnections.Add(networkId.Value, newConnection);
7460
}
7561
}
@@ -79,8 +65,9 @@ protected override void OnUpdate()
7965
{
8066
foreach (var entry in m_NewConnections)
8167
{
82-
// Check if the delay time has passed.
83-
if (entry.Value.IsSynced && entry.Value.ConnectedTime < UnityEngine.Time.realtimeSinceStartup)
68+
// Server: always connect
69+
// Client: wait until we have synchronized before announcing we are ready to receive snapshots
70+
if (networkManager.IsServer || (!networkManager.IsServer && networkManager.IsConnectedClient))
8471
{
8572
// Set the connection in-game
8673
commandBuffer.AddComponent<NetworkStreamInGame>(entry.Value.Entity);
@@ -97,21 +84,29 @@ protected override void OnUpdate()
9784
}
9885
m_TempConnections.Clear();
9986

87+
// If the local NetworkManager is shutting down or no longer connected, then
88+
// make sure we have disconnected all known connections.
89+
if (networkManager.ShutdownInProgress || !networkManager.IsListening)
90+
{
91+
foreach (var (networkId, entity) in SystemAPI.Query<NetworkId>().WithEntityAccess())
92+
{
93+
commandBuffer.RemoveComponent<ConnectionState>(entity);
94+
NetworkManager.OnNetCodeDisconnect?.Invoke(new NetcodeConnection { World = World, Entity = entity, NetworkId = networkId.Value });
95+
}
96+
}
10097
commandBuffer.Playback(EntityManager);
10198
}
10299

100+
/// <summary>
101+
/// Always disconnect all known connections when being destroyed.
102+
/// </summary>
103103
protected override void OnDestroy()
104104
{
105105
var commandBuffer = new EntityCommandBuffer(Allocator.Temp);
106106
foreach (var (networkId, entity) in SystemAPI.Query<NetworkId>().WithEntityAccess())
107107
{
108108
commandBuffer.RemoveComponent<ConnectionState>(entity);
109-
// TODO: maybe disconnect reason?
110-
m_TempConnections.Add(new NetcodeConnection { World = World, Entity = entity, NetworkId = networkId.Value });
111-
}
112-
foreach (var con in m_TempConnections)
113-
{
114-
NetworkManager.OnNetCodeDisconnect?.Invoke(con);
109+
NetworkManager.OnNetCodeDisconnect?.Invoke(new NetcodeConnection { World = World, Entity = entity, NetworkId = networkId.Value });
115110
}
116111
commandBuffer.Playback(EntityManager);
117112
base.OnDestroy();

com.unity.netcode.gameobjects/Runtime/Core/NetworkManager.cs

Lines changed: 20 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,9 @@
88
#endif
99
using Unity.Netcode.Components;
1010
using Unity.Netcode.Runtime;
11+
#if UNIFIED_NETCODE
1112
using Unity.Netcode.Unified;
13+
#endif
1214
using UnityEngine;
1315
#if UNITY_EDITOR
1416
using UnityEditor;
@@ -1204,11 +1206,11 @@ internal void Initialize(bool server)
12041206

12051207
// UnityTransport dependencies are then initialized
12061208
RealTimeProvider = ComponentFactory.Create<IRealTimeProvider>(this);
1207-
1209+
12081210
#if UNIFIED_NETCODE
12091211
NetworkConfig.NetworkTransport = gameObject.AddComponent<UnifiedNetcodeTransport>();
12101212
#endif
1211-
1213+
12121214
MetricsManager.Initialize(this);
12131215

12141216
{
@@ -1320,18 +1322,27 @@ private System.Collections.IEnumerator WaitForHybridPrefabRegistration(StartType
13201322
{
13211323
NetworkLog.LogInfo($"[{nameof(WaitForHybridPrefabRegistration)}] Netcode is not active but has an instance at this point.");
13221324
}
1325+
1326+
/// !! Important !!
1327+
/// Clear out any pre-existing configuration in the event this applicatioin instance has already been connected to a session.
1328+
NetCode.Netcode.Reset();
1329+
1330+
/// !! Initialize worlds here !!
1331+
/// Worlds are created here: <see cref="UnifiedBootStrap.Initialize"/>
13231332
DefaultWorldInitialization.Initialize("Default World", false);
1324-
var waitTime = new WaitForSeconds(0.016f);
1325-
// This should not be needed at this point, but here in the event something changes.
1326-
while (NetworkConfig.Prefabs.HasPendingGhostPrefabs)
1333+
1334+
// This should not be needed at this point, but this is here in the event something changes.
1335+
if (NetworkConfig.Prefabs.HasPendingGhostPrefabs)
13271336
{
1328-
if (LogLevel <= LogLevel.Developer)
1337+
NetworkLog.LogWarning($"[{nameof(WaitForHybridPrefabRegistration)}] !!!!! (Ghosts are still pending registration) !!!!!");
1338+
var waitTime = new WaitForSeconds(0.016f);
1339+
while (NetworkConfig.Prefabs.HasPendingGhostPrefabs)
13291340
{
1330-
NetworkLog.LogInfo($"[{nameof(WaitForHybridPrefabRegistration)}] Ghosts are still pending registration!");
1341+
NetworkConfig.Prefabs.RegisterGhostPrefabs(this);
1342+
yield return waitTime;
13311343
}
1332-
NetworkConfig.Prefabs.RegisterGhostPrefabs(this);
1333-
yield return waitTime;
13341344
}
1345+
13351346
if (LogLevel <= LogLevel.Developer)
13361347
{
13371348
NetworkLog.LogInfo($"[{nameof(WaitForHybridPrefabRegistration)}] All hybrid prefabs have been registered!");

com.unity.netcode.gameobjects/Runtime/Core/NetworkObject.cs

Lines changed: 16 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -257,10 +257,6 @@ private static void CheckPrefabStage(PrefabStage prefabStage)
257257
/// </summary>
258258
internal void OnValidate()
259259
{
260-
#if UNIFIED_NETCODE
261-
UnifiedValidation();
262-
#endif
263-
264260
// Always exit early if we are in prefab edit mode and this instance is the
265261
// prefab instance within the InContext or InIsolation edit scene.
266262
if (s_PrefabInstance == this)
@@ -280,6 +276,10 @@ internal void OnValidate()
280276
return;
281277
}
282278

279+
#if UNIFIED_NETCODE
280+
UnifiedValidation();
281+
#endif
282+
283283
// Get a global object identifier for this network prefab.
284284
var globalId = GlobalObjectId.GetGlobalObjectIdSlow(this);
285285

@@ -1732,10 +1732,19 @@ private void OnDestroy()
17321732
return;
17331733
}
17341734

1735+
var spawnManager = NetworkManager.SpawnManager;
1736+
17351737
// Always attempt to remove from scene changed updates
1736-
networkManager.SpawnManager?.RemoveNetworkObjectFromSceneChangedUpdates(this);
1738+
spawnManager?.RemoveNetworkObjectFromSceneChangedUpdates(this);
17371739

1740+
#if UNIFIED_NETCODE
1741+
spawnManager?.GhostsPendingSpawn.Remove(NetworkObjectId);
1742+
spawnManager?.GhostsPendingSynchronization.Remove(NetworkObjectId);
1743+
// N4E controls this on the client, allow this if there is a ghost
1744+
if (IsSpawned && !HasGhost && !networkManager.ShutdownInProgress)
1745+
#else
17381746
if (IsSpawned && !networkManager.ShutdownInProgress)
1747+
#endif
17391748
{
17401749
// An authorized destroy is when done by the authority instance or done due to a scene event and the NetworkObject
17411750
// was marked as destroy pending scene event (which means the destroy with scene property was set).
@@ -1763,11 +1772,11 @@ private void OnDestroy()
17631772
}
17641773
}
17651774

1766-
if (networkManager.SpawnManager != null && networkManager.SpawnManager.SpawnedObjects.TryGetValue(NetworkObjectId, out var networkObject))
1775+
if (spawnManager != null && spawnManager.SpawnedObjects.TryGetValue(NetworkObjectId, out var networkObject))
17671776
{
17681777
if (this == networkObject)
17691778
{
1770-
networkManager.SpawnManager.OnDespawnObject(networkObject, false);
1779+
spawnManager.OnDespawnObject(networkObject, false);
17711780
}
17721781
}
17731782
}
@@ -3846,7 +3855,6 @@ private void InitGhost()
38463855
{
38473856
Debug.Log($"[{nameof(NetworkObject)}] GhostBridge {name} detected and instantiated.");
38483857
}
3849-
NetworkObjectBridge.NetworkObjectIdChanged += OnNetworkObjectIdChanged;
38503858
if (NetworkObjectBridge.NetworkObjectId.Value != 0)
38513859
{
38523860
RegisterGhostBridge();
@@ -3866,11 +3874,6 @@ internal void RegisterGhostBridge()
38663874
NetworkManager.SpawnManager.RegisterGhostPendingSpawn(this, NetworkObjectBridge.NetworkObjectId.Value);
38673875
}
38683876
}
3869-
3870-
private void OnNetworkObjectIdChanged(ulong networkObjectId)
3871-
{
3872-
RegisterGhostBridge();
3873-
}
38743877
#endif
38753878

38763879
/// <summary>

com.unity.netcode.gameobjects/Runtime/Messaging/Messages/SceneEventMessage.cs

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,3 @@
1-
2-
using Unity.Netcode.Components;
3-
using Unity.Netcode.Unified;
4-
51
namespace Unity.Netcode
62
{
73
// Todo: Would be lovely to get this one nicely formatted with all the data it sends in the struct
@@ -30,11 +26,6 @@ public void Handle(ref NetworkContext context)
3026
{
3127
var networkManager = (NetworkManager)context.SystemOwner;
3228
networkManager.SceneManager.HandleSceneEvent(context.SenderId, m_ReceivedData);
33-
34-
#if UNIFIED_NETCODE
35-
var unifiedConnectionSystem = NetCode.Netcode.GetWorld(false).GetExistingSystemManaged<UnifiedUpdateConnections>();
36-
unifiedConnectionSystem.MarkSync((int)context.SenderId);
37-
#endif
3829
}
3930
}
4031
}

com.unity.netcode.gameobjects/Runtime/SceneManagement/NetworkSceneManager.cs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2740,8 +2740,14 @@ internal void PopulateScenePlacedObjects(Scene sceneToFilterBy, bool clearSceneP
27402740
var globalObjectIdHash = networkObjectInstance.GlobalObjectIdHash;
27412741
var sceneHandle = networkObjectInstance.gameObject.scene.handle;
27422742
// We check to make sure the NetworkManager instance is the same one to be "NetcodeIntegrationTestHelpers" compatible and filter the list on a per scene basis (for additive scenes)
2743+
#if UNIFIED_NETCODE
2744+
if (!networkObjectInstance.HasGhost && networkObjectInstance.IsSceneObject != false && (networkObjectInstance.NetworkManager == NetworkManager ||
2745+
networkObjectInstance.NetworkManagerOwner == null) && sceneHandle == sceneToFilterBy.handle)
2746+
#else
27432747
if (networkObjectInstance.IsSceneObject != false && (networkObjectInstance.NetworkManager == NetworkManager ||
27442748
networkObjectInstance.NetworkManagerOwner == null) && sceneHandle == sceneToFilterBy.handle)
2749+
2750+
#endif
27452751
{
27462752
if (!ScenePlacedObjects.ContainsKey(globalObjectIdHash))
27472753
{

0 commit comments

Comments
 (0)