Skip to content

Commit 269e581

Browse files
authored
Merge branch 'develop-2.0.0' into fix/anticipatednetworktransform_inlocalspace
2 parents 0b1e59a + 3e579ed commit 269e581

2 files changed

Lines changed: 51 additions & 40 deletions

File tree

com.unity.netcode.gameobjects/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ Additional documentation and release notes are available at [Multiplayer Documen
2424

2525
- Fixed AnticipatedNetworkTransform not respecting the InLocalSpace flag (#3995)
2626
- Issue where a NullReferenceException was thrown when a non-authority failed to spawn a NetworkObject. (#4067)
27+
- Issue where the active scene was not being serialized as the 1st scene which could result in various errors including a soft synchronization error if, on the client-side, other synchronized scenes had already been loaded prior to the active scene, which is always loaded as `LoadSceneMode.SingleMode` when client synchronization is set to `LoadSceneMode.SingleMode`, resulting in the previously loaded scene(s) to be unloaded. (#4065)
2728
- Issue when FastBufferReader is attempting to read a string and all or a portion of the character count has already been read by user script, it could read a character length that results in a negative byte length which could result in an editor crash. (#4052)
2829
- Issue where NetworkRigidbodyBase was not applying rotation correctly when using Rigidbody2D. (#4012)
2930
- Issue where NetworkRigidbodyBase was always checking the 3D rigid body's interpolation mode when determining if it is kinematic and needs to put the rigid body to sleep and then switch to interpolation. (#4012)

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

Lines changed: 50 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -1951,6 +1951,21 @@ private void OnClientLoadedScene(uint sceneEventId, Scene scene)
19511951
/// </summary>
19521952
internal List<ulong> ClientConnectionQueue = new List<ulong>();
19531953

1954+
1955+
[MethodImpl(MethodImplOptions.AggressiveInlining)]
1956+
private void AddSceneToClientSynchronization(ref SceneEventData sceneEventData, ref Scene scene)
1957+
{
1958+
// If we are just a normal client and in distributed authority mode, then always use the known server scene handle
1959+
if (NetworkManager.DistributedAuthorityMode && NetworkManager.CMBServiceConnection)
1960+
{
1961+
sceneEventData.AddSceneToSynchronize(SceneHashFromNameOrPath(scene.path), ClientSceneHandleToServerSceneHandle[scene.handle]);
1962+
}
1963+
else
1964+
{
1965+
sceneEventData.AddSceneToSynchronize(SceneHashFromNameOrPath(scene.path), scene.handle);
1966+
}
1967+
}
1968+
19541969
/// <summary>
19551970
/// Server Side:
19561971
/// This is used for players that have just had their connection approved and will assure they are synchronized
@@ -2001,61 +2016,53 @@ internal void SynchronizeNetworkObjects(ulong clientId, bool synchronizingServic
20012016

20022017
// Organize how (and when) we serialize our NetworkObjects
20032018
var hasSynchronizedActive = false;
2004-
for (int i = 0; i < SceneManager.sceneCount; i++)
2005-
{
2006-
var scene = SceneManager.GetSceneAt(i);
20072019

2008-
// NetworkSceneManager does not synchronize scenes that are not loaded by NetworkSceneManager
2009-
// unless the scene in question is the currently active scene.
2010-
if (ExcludeSceneFromSychronization != null && !ExcludeSceneFromSychronization(scene))
2020+
// It is possible a user might not want to synchronize the active scene, so we will check to see if it is valid before adding it to the synchronization list.
2021+
// !! Important !!
2022+
// The active scene MUST always be the first scene in the synchronization list.
2023+
if (ValidateSceneBeforeLoading(activeScene.buildIndex, activeScene.name, sceneEventData.LoadSceneMode))
2024+
{
2025+
sceneEventData.SceneHash = SceneHashFromNameOrPath(activeScene.path);
2026+
if (sceneEventData.SceneHash == sceneEventData.ActiveSceneHash)
20112027
{
2012-
continue;
2028+
hasSynchronizedActive = true;
20132029
}
20142030

2015-
if (scene == DontDestroyOnLoadScene)
2031+
// If we are just a normal client, then always use the server scene handle
2032+
if (NetworkManager.DistributedAuthorityMode)
20162033
{
2017-
continue;
2034+
sceneEventData.SenderClientId = NetworkManager.LocalClientId;
2035+
sceneEventData.SceneHandle = ClientSceneHandleToServerSceneHandle[activeScene.handle];
20182036
}
2019-
2020-
// This would depend upon whether we are additive or not
2021-
// If we are the base scene, then we set the root scene index;
2022-
if (activeScene == scene)
2037+
else
20232038
{
2024-
if (!ValidateSceneBeforeLoading(scene.buildIndex, scene.name, sceneEventData.LoadSceneMode))
2025-
{
2026-
continue;
2027-
}
2028-
sceneEventData.SceneHash = SceneHashFromNameOrPath(scene.path);
2029-
if (sceneEventData.SceneHash == sceneEventData.ActiveSceneHash)
2030-
{
2031-
hasSynchronizedActive = true;
2032-
}
2033-
2034-
// If we are just a normal client, then always use the server scene handle
2035-
if (NetworkManager.DistributedAuthorityMode)
2036-
{
2037-
sceneEventData.SenderClientId = NetworkManager.LocalClientId;
2038-
sceneEventData.SceneHandle = ClientSceneHandleToServerSceneHandle[scene.handle];
2039-
}
2040-
else
2041-
{
2042-
sceneEventData.SceneHandle = scene.handle;
2043-
}
2039+
sceneEventData.SceneHandle = activeScene.handle;
20442040
}
2045-
else if (!ValidateSceneBeforeLoading(scene.buildIndex, scene.name, LoadSceneMode.Additive))
2041+
AddSceneToClientSynchronization(ref sceneEventData, ref activeScene);
2042+
}
2043+
2044+
for (int i = 0; i < SceneManager.sceneCount; i++)
2045+
{
2046+
var scene = SceneManager.GetSceneAt(i);
2047+
// Skip adding the active scene at this point as we are just adding all other additively loaded scenes to the synchronization list.
2048+
// Skip adding the dont destroy on load scene as that is never synchronized.
2049+
if ((scene.handle == activeScene.handle) || (scene == DontDestroyOnLoadScene))
20462050
{
20472051
continue;
20482052
}
20492053

2050-
// If we are just a normal client and in distributed authority mode, then always use the known server scene handle
2051-
if (NetworkManager.DistributedAuthorityMode && NetworkManager.CMBServiceConnection)
2054+
// NetworkSceneManager does not synchronize scenes that are not loaded by NetworkSceneManager
2055+
// unless the scene in question is the currently active scene.
2056+
if (ExcludeSceneFromSychronization != null && !ExcludeSceneFromSychronization(scene))
20522057
{
2053-
sceneEventData.AddSceneToSynchronize(SceneHashFromNameOrPath(scene.path), ClientSceneHandleToServerSceneHandle[scene.handle]);
2058+
continue;
20542059
}
2055-
else
2060+
2061+
if (!ValidateSceneBeforeLoading(scene.buildIndex, scene.name, LoadSceneMode.Additive))
20562062
{
2057-
sceneEventData.AddSceneToSynchronize(SceneHashFromNameOrPath(scene.path), scene.handle);
2063+
continue;
20582064
}
2065+
AddSceneToClientSynchronization(ref sceneEventData, ref scene);
20592066
}
20602067

20612068
if (!hasSynchronizedActive && NetworkManager.CMBServiceConnection && synchronizingService)
@@ -2108,9 +2115,12 @@ private void OnClientBeginSync(uint sceneEventId)
21082115
var sceneHash = sceneEventData.GetNextSceneSynchronizationHash();
21092116
var sceneHandle = sceneEventData.GetNextSceneSynchronizationHandle();
21102117
var sceneName = SceneNameFromHash(sceneHash);
2118+
var activeSceneName = SceneNameFromHash(sceneEventData.ActiveSceneHash);
21112119
var activeScene = SceneManager.GetActiveScene();
21122120

2113-
var loadSceneMode = sceneHash == sceneEventData.SceneHash ? sceneEventData.LoadSceneMode : LoadSceneMode.Additive;
2121+
var activeSceneLoaded = activeSceneName == activeScene.name;
2122+
2123+
var loadSceneMode = sceneHash == sceneEventData.SceneHash && !activeSceneLoaded ? sceneEventData.LoadSceneMode : LoadSceneMode.Additive;
21142124

21152125
// Store the sceneHandle and hash
21162126
sceneEventData.NetworkSceneHandle = sceneHandle;

0 commit comments

Comments
 (0)