@@ -19,6 +19,28 @@ public NetworkPrefabHandlerSynchronizationTests(HostOrServer hostOrServer) : bas
1919 private GameObject m_ClientSideValidPrefab ;
2020 private GameObject m_ClientSideExceptionPrefab ;
2121
22+ public class VerifyLastClientSentRpcToServer : NetworkBehaviour
23+ {
24+ public bool RpcReceived { get ; private set ; }
25+
26+ protected override void OnNetworkPreSpawn ( ref NetworkManager networkManager )
27+ {
28+ RpcReceived = false ;
29+ base . OnNetworkPreSpawn ( ref networkManager ) ;
30+ }
31+
32+ public void DelayUntilOneMessageReceivedRpc ( RpcParams rpcParams = default )
33+ {
34+ RpcReceived = true ;
35+ }
36+ }
37+
38+ protected override void OnCreatePlayerPrefab ( )
39+ {
40+ m_PlayerPrefab . AddComponent < VerifyLastClientSentRpcToServer > ( ) ;
41+ base . OnCreatePlayerPrefab ( ) ;
42+ }
43+
2244 protected override void OnServerAndClientsCreated ( )
2345 {
2446 m_ValidPrefab = CreateNetworkObjectPrefab ( "ValidPrefab" ) ;
@@ -28,17 +50,22 @@ protected override void OnServerAndClientsCreated()
2850 }
2951
3052 [ UnityTest ]
31- [ UnityPlatform ( exclude = new [ ] { RuntimePlatform . IPhonePlayer , RuntimePlatform . OSXPlayer , RuntimePlatform . OSXEditor } ) ] // Ignored test tracked in MTT-15473
3253 public IEnumerator NetworkPrefabHandlerSpawnAndSynchronizeTests ( )
3354 {
3455 var nonAuthority = GetNonAuthorityNetworkManager ( ) ;
3556
3657 var networkObjectToSpawnOnClient = m_ClientSideValidPrefab . GetComponent < NetworkObject > ( ) ;
37- nonAuthority . PrefabHandler . AddHandler ( m_ClientSideExceptionPrefab , new NetworkPrefabExceptionThrower ( ) ) ;
38- var prefabHandlerObject = new GameObject ( ) ;
39- var prefabHandler = prefabHandlerObject . AddComponent < NetworkPrefabInstanceHandler > ( ) ;
40- prefabHandler . Initialize ( nonAuthority , m_ValidPrefab . GetComponent < NetworkObject > ( ) ) ;
41- //nonAuthority.PrefabHandler.AddHandler(m_ValidPrefab, new NetworkPrefabInstanceHandler(networkObjectToSpawnOnClient));
58+
59+ var clientSideHandler = new GameObject ( ) ;
60+ var clientPrefabHandler = clientSideHandler . AddComponent < NetworkPrefabInstanceHandler > ( ) ;
61+ clientPrefabHandler . Initialize ( nonAuthority , m_ClientSideValidPrefab . GetComponent < NetworkObject > ( ) ) ;
62+
63+ nonAuthority . PrefabHandler . AddHandler ( m_ValidPrefab , clientPrefabHandler ) ;
64+
65+ var clientSideExceptionHandler = new GameObject ( ) ;
66+ var clientSideExceptionPrefabHandler = clientSideExceptionHandler . AddComponent < NetworkPrefabExceptionThrower > ( ) ;
67+
68+ nonAuthority . PrefabHandler . AddHandler ( m_ClientSideExceptionPrefab , clientSideExceptionPrefabHandler ) ;
4269
4370 var authority = GetAuthorityNetworkManager ( ) ;
4471
@@ -63,14 +90,16 @@ public IEnumerator NetworkPrefabHandlerSpawnAndSynchronizeTests()
6390
6491 // Create a new client and register the same PrefabHandlers on the client
6592 var newClient = CreateNewClient ( ) ;
66- var prefabHandlerObject2 = new GameObject ( ) ;
67- var prefabHandler2 = prefabHandlerObject2 . AddComponent < NetworkPrefabExceptionThrower > ( ) ;
6893
69- newClient . PrefabHandler . AddHandler ( m_ClientSideExceptionPrefab , new NetworkPrefabExceptionThrower ( ) ) ;
94+ var lateJoinClientSideHandler = new GameObject ( ) ;
95+ var lateJoinClientPrefabHandler = clientSideHandler . AddComponent < NetworkPrefabInstanceHandler > ( ) ;
96+ var lateJoinExceptionHandler = new GameObject ( ) ;
97+ var lateJoinClientExceptionHandler = lateJoinExceptionHandler . AddComponent < NetworkPrefabExceptionThrower > ( ) ;
7098
71- var prefabHandlerObject3 = new GameObject ( ) ;
72- var prefabHandler3 = prefabHandlerObject3 . AddComponent < NetworkPrefabInstanceHandler > ( ) ;
73- prefabHandler3 . Initialize ( nonAuthority , networkObjectToSpawnOnClient ) ;
99+ lateJoinClientPrefabHandler . Initialize ( newClient , m_ClientSideValidPrefab . GetComponent < NetworkObject > ( ) ) ;
100+
101+ newClient . PrefabHandler . AddHandler ( m_ClientSideExceptionPrefab , lateJoinClientExceptionHandler ) ;
102+ newClient . PrefabHandler . AddHandler ( m_ValidPrefab , lateJoinClientPrefabHandler ) ;
74103
75104 // Expect assertions from the new client
76105 LogAssert . Expect ( LogType . Exception , "Exception: exception while instantiating" ) ;
@@ -82,6 +111,8 @@ public IEnumerator NetworkPrefabHandlerSpawnAndSynchronizeTests()
82111
83112 // Start and synchronize the new client
84113 yield return StartClient ( newClient ) ;
114+ AssertOnTimeout ( $ "Timed out waiting for the late joining client, { newClient . name } , to connect!") ;
115+
85116
86117 // Validate the valid prefab spawned on all clients without issue
87118 var expectedAuthorityHash = m_ValidPrefab . GetComponent < NetworkObject > ( ) . GlobalObjectIdHash ;
@@ -102,7 +133,20 @@ public IEnumerator NetworkPrefabHandlerSpawnAndSynchronizeTests()
102133 }
103134 }
104135
105- Object . Destroy ( prefabHandlerObject ) ;
136+ // Assure this test continues to run until we verify the late joining client has sent 1 message to the server
137+ // This should be the fix for MTT-15473 where the test finishes/exits before the message from the client has been received and processed by the server.
138+ Assert . IsTrue ( authority . SpawnManager . SpawnedObjects . ContainsKey ( newClient . LocalClient . PlayerObject . NetworkObjectId ) , $ "Server does not have a player for Client-{ newClient . LocalClientId } !") ;
139+
140+ // Get server and late joining client's VerifyLastClientSentRpcToServer NetworkBehaviour
141+ var serverLateClientInstance = authority . SpawnManager . SpawnedObjects [ newClient . LocalClient . PlayerObject . NetworkObjectId ] . GetComponent < VerifyLastClientSentRpcToServer > ( ) ;
142+ var sendRpc = newClient . LocalClient . PlayerObject . GetComponent < VerifyLastClientSentRpcToServer > ( ) ;
143+
144+ // Send a message from the late joining client to the server
145+ sendRpc . DelayUntilOneMessageReceivedRpc ( ) ;
146+
147+ // Wait for the server to have received this message before exiting the test.
148+ // If the log message has not been received by the server at this point, then there is some other type of bug specific to iOS and Mac.
149+ yield return WaitForConditionOrTimeOut ( ( ) => serverLateClientInstance . RpcReceived ) ;
106150 }
107151 }
108152}
0 commit comments