Skip to content

Commit b7de156

Browse files
committed
redo #1030
1 parent 89a92fb commit b7de156

File tree

6 files changed

+391
-336
lines changed

6 files changed

+391
-336
lines changed

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

Lines changed: 87 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,10 @@ public class NetworkSceneManager
9696
/// </summary>
9797
private static bool s_IsSceneEventActive = false;
9898

99+
#if UNITY_EDITOR || DEVELOPMENT_BUILD
100+
private bool m_IsRunningUnitTest = SceneManager.GetActiveScene().name.StartsWith("InitTestScene");
101+
#endif
102+
99103
/// <summary>
100104
/// The delegate callback definition for scene event notifications
101105
/// For more details review over <see cref="SceneEvent"/> and <see cref="SceneEventData"/>
@@ -538,11 +542,23 @@ private void OnClientUnloadScene()
538542
$"because the client scene handle {sceneHandle} was not found in ScenesLoaded!");
539543
}
540544
s_IsSceneEventActive = true;
541-
542-
var sceneUnload = SceneManager.UnloadSceneAsync(ScenesLoaded[sceneHandle]);
543-
545+
var sceneUnload = (AsyncOperation)null;
546+
#if UNITY_EDITOR || DEVELOPMENT_BUILD
547+
// In unit tests, we don't allow clients to unload scenes since
548+
// MultiInstance unit tests share the same scene space.
549+
if (m_IsRunningUnitTest)
550+
{
551+
sceneUnload = new AsyncOperation();
552+
}
553+
else
554+
{
555+
sceneUnload = SceneManager.UnloadSceneAsync(ScenesLoaded[sceneHandle]);
556+
sceneUnload.completed += asyncOp2 => OnSceneUnloaded();
557+
}
558+
#else
559+
sceneUnload = SceneManager.UnloadSceneAsync(ScenesLoaded[sceneHandle]);
544560
sceneUnload.completed += asyncOp2 => OnSceneUnloaded();
545-
561+
#endif
546562
ScenesLoaded.Remove(sceneHandle);
547563

548564
// Remove our server to scene handle lookup
@@ -559,6 +575,11 @@ private void OnClientUnloadScene()
559575
});
560576

561577

578+
#if UNITY_EDITOR
579+
OnSceneUnloaded();
580+
#endif
581+
582+
562583
}
563584

564585
/// <summary>
@@ -704,6 +725,35 @@ private void OnClientSceneLoadingEvent(Stream objectStream)
704725
return;
705726
}
706727

728+
#if UNITY_EDITOR || DEVELOPMENT_BUILD
729+
// In unit tests, we don't allow clients to load additional scenes since
730+
// MultiInstance unit tests share the same scene space.
731+
if (m_IsRunningUnitTest)
732+
{
733+
// Send the loading message
734+
OnSceneEvent?.Invoke(new SceneEvent()
735+
{
736+
AsyncOperation = new AsyncOperation(),
737+
SceneEventType = SceneEventData.SceneEventType,
738+
LoadSceneMode = SceneEventData.LoadSceneMode,
739+
SceneName = sceneName,
740+
ClientId = m_NetworkManager.LocalClientId
741+
});
742+
743+
// Unit tests must mirror the server's scenes loaded dictionary, otherwise this portion will fail
744+
if (ScenesLoaded.ContainsKey(SceneEventData.SceneHandle))
745+
{
746+
OnClientLoadedScene(ScenesLoaded[SceneEventData.SceneHandle]);
747+
}
748+
else
749+
{
750+
throw new Exception($"Could not find the scene handle {SceneEventData.SceneHandle} for scene {GetSceneNameFromNetcodeSceneIndex(SceneEventData.SceneIndex)} " +
751+
$"during unit test. Did you forget to register this in the unit test?");
752+
}
753+
return;
754+
}
755+
#endif
756+
707757
if (SceneEventData.LoadSceneMode == LoadSceneMode.Single)
708758
{
709759
// Move ALL NetworkObjects to the temp scene
@@ -973,25 +1023,44 @@ private void OnClientBeginSync()
9731023
ScenePlacedObjects.Clear();
9741024
}
9751025

1026+
var shouldPassThrough = false;
1027+
var sceneLoad = (AsyncOperation)null;
1028+
9761029
// Check to see if the client already has loaded the scene to be loaded
977-
if (sceneName != activeScene.name)
1030+
if (sceneName == activeScene.name)
9781031
{
979-
// If not, then load the scene
980-
var sceneLoad = SceneManager.LoadSceneAsync(sceneName, loadSceneMode);
981-
982-
// Notify local client that a scene load has begun
983-
OnSceneEvent?.Invoke(new SceneEvent()
984-
{
985-
AsyncOperation = sceneLoad,
986-
SceneEventType = SceneEventData.SceneEventTypes.S2C_Load,
987-
LoadSceneMode = loadSceneMode,
988-
SceneName = sceneName,
989-
ClientId = m_NetworkManager.LocalClientId,
990-
});
1032+
// If the client is already in the same scene, then pass through and
1033+
// don't try to reload it.
1034+
shouldPassThrough = true;
1035+
}
9911036

1037+
#if UNITY_EDITOR || DEVELOPMENT_BUILD
1038+
if (m_IsRunningUnitTest)
1039+
{
1040+
// In unit tests, we don't allow clients to load additional scenes since
1041+
// MultiInstance unit tests share the same scene space.
1042+
shouldPassThrough = true;
1043+
sceneLoad = new AsyncOperation();
1044+
}
1045+
#endif
1046+
if (!shouldPassThrough)
1047+
{
1048+
// If not, then load the scene
1049+
sceneLoad = SceneManager.LoadSceneAsync(sceneName, loadSceneMode);
9921050
sceneLoad.completed += asyncOp2 => ClientLoadedSynchronization(sceneIndex, sceneHandle);
9931051
}
994-
else
1052+
1053+
// Notify local client that a scene load has begun
1054+
OnSceneEvent?.Invoke(new SceneEvent()
1055+
{
1056+
AsyncOperation = sceneLoad,
1057+
SceneEventType = SceneEventData.SceneEventTypes.S2C_Load,
1058+
LoadSceneMode = loadSceneMode,
1059+
SceneName = sceneName,
1060+
ClientId = m_NetworkManager.LocalClientId,
1061+
});
1062+
1063+
if(shouldPassThrough)
9951064
{
9961065
// If so, then pass through
9971066
ClientLoadedSynchronization(sceneIndex, sceneHandle);

com.unity.netcode.gameobjects/Tests/Runtime/NetworkSceneManagerTests.cs

Lines changed: 0 additions & 45 deletions
This file was deleted.

0 commit comments

Comments
 (0)