@@ -96,6 +96,10 @@ public class NetworkSceneManager
96
96
/// </summary>
97
97
private static bool s_IsSceneEventActive = false ;
98
98
99
+ #if UNITY_EDITOR || DEVELOPMENT_BUILD
100
+ private bool m_IsRunningUnitTest = SceneManager . GetActiveScene ( ) . name . StartsWith ( "InitTestScene" ) ;
101
+ #endif
102
+
99
103
/// <summary>
100
104
/// The delegate callback definition for scene event notifications
101
105
/// For more details review over <see cref="SceneEvent"/> and <see cref="SceneEventData"/>
@@ -538,11 +542,23 @@ private void OnClientUnloadScene()
538
542
$ "because the client scene handle { sceneHandle } was not found in ScenesLoaded!") ;
539
543
}
540
544
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 ] ) ;
544
560
sceneUnload . completed += asyncOp2 => OnSceneUnloaded ( ) ;
545
-
561
+ #endif
546
562
ScenesLoaded . Remove ( sceneHandle ) ;
547
563
548
564
// Remove our server to scene handle lookup
@@ -559,6 +575,11 @@ private void OnClientUnloadScene()
559
575
} ) ;
560
576
561
577
578
+ #if UNITY_EDITOR
579
+ OnSceneUnloaded ( ) ;
580
+ #endif
581
+
582
+
562
583
}
563
584
564
585
/// <summary>
@@ -704,6 +725,35 @@ private void OnClientSceneLoadingEvent(Stream objectStream)
704
725
return ;
705
726
}
706
727
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
+
707
757
if ( SceneEventData . LoadSceneMode == LoadSceneMode . Single )
708
758
{
709
759
// Move ALL NetworkObjects to the temp scene
@@ -973,25 +1023,44 @@ private void OnClientBeginSync()
973
1023
ScenePlacedObjects . Clear ( ) ;
974
1024
}
975
1025
1026
+ var shouldPassThrough = false ;
1027
+ var sceneLoad = ( AsyncOperation ) null ;
1028
+
976
1029
// Check to see if the client already has loaded the scene to be loaded
977
- if ( sceneName ! = activeScene . name )
1030
+ if ( sceneName = = activeScene . name )
978
1031
{
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
+ }
991
1036
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 ) ;
992
1050
sceneLoad . completed += asyncOp2 => ClientLoadedSynchronization ( sceneIndex , sceneHandle ) ;
993
1051
}
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 )
995
1064
{
996
1065
// If so, then pass through
997
1066
ClientLoadedSynchronization ( sceneIndex , sceneHandle ) ;
0 commit comments