Skip to content

Commit 81ebc04

Browse files
fix
Issue where distributed authority would throw an exception during scene migration due to the fact that we would throw an exception if the 1st scene in the scene migration table didn't contain the client that has authority over the NetworkObject that migrated into a new scene. Now we count how many entries were written and if that count is zero upon parsing known loaded scenes then it throws an exception. Reverting the exclusion of DDOL synchronization (that was a red herring).
1 parent df4a03a commit 81ebc04

3 files changed

Lines changed: 30 additions & 15 deletions

File tree

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

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3661,12 +3661,6 @@ internal void SceneChangedUpdate(Scene scene, bool notify = false)
36613661
return;
36623662
}
36633663

3664-
// Don't create notification if the scene is the DDOL.
3665-
if (scene == NetworkManager.SceneManager.DontDestroyOnLoadScene)
3666-
{
3667-
return;
3668-
}
3669-
36703664
SceneOriginHandle = scene.handle;
36713665

36723666
// non-authority needs to update the NetworkSceneHandle

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3059,6 +3059,7 @@ internal void CheckForAndSendNetworkObjectSceneChanged()
30593059
// Some NetworkObjects still exist, send the message
30603060
var sceneEvent = BeginSceneEvent();
30613061
sceneEvent.SceneEventType = SceneEventType.ObjectSceneChanged;
3062+
// SendSceneEventData can throw an exception. We need to wrap this and recover from the exception gracefully.
30623063
try
30633064
{
30643065
SendSceneEventData(sceneEvent.SceneEventId, NetworkManager.ConnectedClientsIds.Where(c => c != NetworkManager.LocalClientId).ToArray());

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

Lines changed: 29 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1204,31 +1204,51 @@ private void ReadSceneEventProgressDone(FastBufferReader reader)
12041204
private void SerializeObjectsMovedIntoNewScene(FastBufferWriter writer)
12051205
{
12061206
var sceneManager = m_NetworkManager.SceneManager;
1207-
var ownerId = m_NetworkManager.LocalClientId;
1207+
var networkManagerClientId = m_NetworkManager.LocalClientId;
12081208
if (IsForwarding)
12091209
{
1210-
ownerId = m_OwnerId;
1210+
networkManagerClientId = m_OwnerId;
12111211
}
12121212

12131213
// Write the owner identifier
1214-
writer.WriteValueSafe(ownerId);
1214+
writer.WriteValueSafe(networkManagerClientId);
12151215

1216-
// Write the number of scene handles
1217-
writer.WriteValueSafe(sceneManager.ObjectsMigratedIntoNewScene.Count);
1216+
// Create a place holder for the number of entries written.
1217+
// Distributed authority this could end up being just a single entry for
1218+
// one of several scenes loaded. As such, we need to count how many entries
1219+
// are actually written.
1220+
var countPosition = writer.Position;
1221+
writer.WriteValueSafe(0);
1222+
var entriesWritten = 0;
12181223
foreach (var sceneHandleObjects in sceneManager.ObjectsMigratedIntoNewScene)
12191224
{
1220-
if (!sceneHandleObjects.Value.ContainsKey(ownerId))
1225+
// Since these are separated by scene then owner, there could be scenes that have
1226+
// no changes.
1227+
if (!sceneHandleObjects.Value.ContainsKey(networkManagerClientId))
12211228
{
1222-
throw new Exception($"Trying to send object scene migration for Client-{ownerId} but the client has no entries to send!");
1229+
continue;
12231230
}
12241231
// Write the scene handle
12251232
writer.WriteValueSafe(sceneHandleObjects.Key);
12261233
// Write the number of NetworkObjectIds to expect
1227-
writer.WriteValueSafe(sceneHandleObjects.Value[ownerId].Count);
1228-
foreach (var networkObject in sceneHandleObjects.Value[ownerId])
1234+
writer.WriteValueSafe(sceneHandleObjects.Value[networkManagerClientId].Count);
1235+
foreach (var networkObject in sceneHandleObjects.Value[networkManagerClientId])
12291236
{
12301237
writer.WriteValueSafe(networkObject.NetworkObjectId);
12311238
}
1239+
entriesWritten++;
1240+
}
1241+
if (entriesWritten == 0)
1242+
{
1243+
throw new Exception($"Trying to send object scene migration for Client-{networkManagerClientId} but the client has no entries to send!");
1244+
}
1245+
else
1246+
{
1247+
// Write the number of entries written
1248+
var endPosition = writer.Position;
1249+
writer.Seek(countPosition);
1250+
writer.WriteValueSafe(entriesWritten);
1251+
writer.Seek(endPosition);
12321252
}
12331253
}
12341254

0 commit comments

Comments
 (0)