11using System ;
22using System . Collections ;
3+ using System . Collections . Generic ;
34using UnityEngine . TestTools ;
45using NUnit . Framework ;
56using Unity . Netcode . TestHelpers . Runtime ;
@@ -20,11 +21,59 @@ public struct MyTypeThree
2021 {
2122 public int Value ;
2223 }
23- public class WorkingUserNetworkVariableComponent : NetworkBehaviour
24+
25+ /// <summary>
26+ /// Used to help track instances of any child derived class
27+ /// </summary>
28+ public class WorkingUserNetworkVariableComponentBase : NetworkBehaviour
29+ {
30+ private static Dictionary < ulong , WorkingUserNetworkVariableComponentBase > s_Instances = new Dictionary < ulong , WorkingUserNetworkVariableComponentBase > ( ) ;
31+
32+ internal static T GetRelativeInstance < T > ( ulong clientId ) where T : NetworkBehaviour
33+ {
34+ if ( s_Instances . ContainsKey ( clientId ) )
35+ {
36+ return s_Instances [ clientId ] as T ;
37+ }
38+ return null ;
39+ }
40+
41+ public static void Reset ( )
42+ {
43+ s_Instances . Clear ( ) ;
44+ }
45+
46+ public override void OnNetworkSpawn ( )
47+ {
48+ if ( ! s_Instances . ContainsKey ( NetworkManager . LocalClientId ) )
49+ {
50+ s_Instances . Add ( NetworkManager . LocalClientId , this ) ;
51+ }
52+ else
53+ {
54+ Debug . LogWarning ( $ "{ name } is spawned but client id { NetworkManager . LocalClientId } instance already exists!") ;
55+ }
56+ }
57+
58+ public override void OnNetworkDespawn ( )
59+ {
60+ if ( s_Instances . ContainsKey ( NetworkManager . LocalClientId ) )
61+ {
62+ s_Instances . Remove ( NetworkManager . LocalClientId ) ;
63+ }
64+ else
65+ {
66+ Debug . LogWarning ( $ "{ name } is was never spawned but client id { NetworkManager . LocalClientId } is trying to despawn it!") ;
67+ }
68+ }
69+ }
70+
71+ public class WorkingUserNetworkVariableComponent : WorkingUserNetworkVariableComponentBase
2472 {
2573 public NetworkVariable < MyTypeOne > NetworkVariable = new NetworkVariable < MyTypeOne > ( ) ;
2674 }
27- public class WorkingUserNetworkVariableComponentUsingExtensionMethod : NetworkBehaviour
75+
76+ public class WorkingUserNetworkVariableComponentUsingExtensionMethod : WorkingUserNetworkVariableComponentBase
2877 {
2978 public NetworkVariable < MyTypeTwo > NetworkVariable = new NetworkVariable < MyTypeTwo > ( ) ;
3079 }
@@ -60,6 +109,12 @@ public NetworkVariableUserSerializableTypesTests()
60109 private GameObject m_ExtensionMethodPrefab ;
61110 private GameObject m_NonWorkingPrefab ;
62111
112+ protected override IEnumerator OnSetup ( )
113+ {
114+ WorkingUserNetworkVariableComponentBase . Reset ( ) ;
115+ return base . OnSetup ( ) ;
116+ }
117+
63118 protected override void OnServerAndClientsCreated ( )
64119 {
65120 m_WorkingPrefab = CreateNetworkObjectPrefab ( $ "[{ nameof ( NetworkVariableUserSerializableTypesTests ) } .{ nameof ( m_WorkingPrefab ) } ]") ;
@@ -70,17 +125,10 @@ protected override void OnServerAndClientsCreated()
70125 m_NonWorkingPrefab . AddComponent < NonWorkingUserNetworkVariableComponent > ( ) ;
71126 }
72127
73- private T GetComponentForClient < T > ( ulong clientId ) where T : NetworkBehaviour
128+ private bool CheckForClientInstance < T > ( ) where T : WorkingUserNetworkVariableComponentBase
74129 {
75- foreach ( var component in Object . FindObjectsOfType < T > ( ) )
76- {
77- if ( component . IsSpawned && component . NetworkManager . LocalClientId == clientId )
78- {
79- return component ;
80- }
81- }
82-
83- return null ;
130+ var instance = WorkingUserNetworkVariableComponentBase . GetRelativeInstance < T > ( m_ClientNetworkManagers [ 0 ] . LocalClientId ) ;
131+ return instance != null && instance . IsSpawned ;
84132 }
85133
86134 [ UnityTest ]
@@ -95,22 +143,28 @@ public IEnumerator WhenUsingAUserSerializableNetworkVariableWithUserSerializatio
95143 value = new MyTypeOne ( ) ;
96144 reader . ReadValueSafe ( out value . Value ) ;
97145 } ;
98- var serverObject = Object . Instantiate ( m_WorkingPrefab ) ;
146+
147+ var serverObject = SpawnObject ( m_WorkingPrefab , m_ServerNetworkManager ) ;
99148 var serverNetworkObject = serverObject . GetComponent < NetworkObject > ( ) ;
100- serverNetworkObject . NetworkManagerOwner = m_ServerNetworkManager ;
101- serverNetworkObject . Spawn ( ) ;
102149
103- yield return NetcodeIntegrationTestHelpers . WaitForMessageOfTypeReceived < CreateObjectMessage > ( m_ClientNetworkManagers [ 0 ] ) ;
150+ // Wait for the client instance to be spawned, which removes the need to check for two NetworkVariableDeltaMessages
151+ yield return WaitForConditionOrTimeOut ( ( ) => CheckForClientInstance < WorkingUserNetworkVariableComponent > ( ) ) ;
152+ AssertOnTimeout ( $ "Timed out waiting for the client side object to spawn!") ;
104153
105- serverNetworkObject . GetComponent < WorkingUserNetworkVariableComponent > ( ) . NetworkVariable . Value = new MyTypeOne { Value = 20 } ;
154+ // Get server and client instances of the test component
155+ var clientInstance = WorkingUserNetworkVariableComponentBase . GetRelativeInstance < WorkingUserNetworkVariableComponent > ( m_ClientNetworkManagers [ 0 ] . LocalClientId ) ;
156+ var serverInstance = serverNetworkObject . GetComponent < WorkingUserNetworkVariableComponent > ( ) ;
106157
107- yield return NetcodeIntegrationTestHelpers . WaitForMessageOfTypeReceived < NetworkVariableDeltaMessage > ( m_ClientNetworkManagers [ 0 ] ) ;
108- yield return NetcodeIntegrationTestHelpers . WaitForMessageOfTypeReceived < NetworkVariableDeltaMessage > ( m_ClientNetworkManagers [ 0 ] ) ;
158+ // Set the server side value
159+ serverInstance . NetworkVariable . Value = new MyTypeOne { Value = 20 } ;
109160
110- var clientObject = GetComponentForClient < WorkingUserNetworkVariableComponent > ( m_ClientNetworkManagers [ 0 ] . LocalClientId ) ;
161+ // Wait for the NetworkVariableDeltaMessage
162+ yield return NetcodeIntegrationTestHelpers . WaitForMessageOfTypeReceived < NetworkVariableDeltaMessage > ( m_ClientNetworkManagers [ 0 ] ) ;
111163
112- Assert . AreEqual ( serverNetworkObject . GetComponent < WorkingUserNetworkVariableComponent > ( ) . NetworkVariable . Value . Value , clientObject . NetworkVariable . Value . Value ) ;
113- Assert . AreEqual ( 20 , clientObject . NetworkVariable . Value . Value ) ;
164+ // Wait for the client side value to be updated to the server side value (can take an additional frame)
165+ yield return WaitForConditionOrTimeOut ( ( ) => clientInstance . NetworkVariable . Value . Value == serverInstance . NetworkVariable . Value . Value ) ;
166+ Assert . AreEqual ( serverNetworkObject . GetComponent < WorkingUserNetworkVariableComponent > ( ) . NetworkVariable . Value . Value , clientInstance . NetworkVariable . Value . Value ) ;
167+ Assert . AreEqual ( 20 , clientInstance . NetworkVariable . Value . Value ) ;
114168 }
115169
116170 [ UnityTest ]
@@ -119,22 +173,27 @@ public IEnumerator WhenUsingAUserSerializableNetworkVariableWithUserSerializatio
119173 UserNetworkVariableSerialization < MyTypeTwo > . WriteValue = NetworkVariableUserSerializableTypesTestsExtensionMethods . WriteValueSafe ;
120174 UserNetworkVariableSerialization < MyTypeTwo > . ReadValue = NetworkVariableUserSerializableTypesTestsExtensionMethods . ReadValueSafe ;
121175
122- var serverObject = Object . Instantiate ( m_ExtensionMethodPrefab ) ;
176+ var serverObject = SpawnObject ( m_ExtensionMethodPrefab , m_ServerNetworkManager ) ;
123177 var serverNetworkObject = serverObject . GetComponent < NetworkObject > ( ) ;
124- serverNetworkObject . NetworkManagerOwner = m_ServerNetworkManager ;
125- serverNetworkObject . Spawn ( ) ;
126178
127- yield return NetcodeIntegrationTestHelpers . WaitForMessageOfTypeReceived < CreateObjectMessage > ( m_ClientNetworkManagers [ 0 ] ) ;
179+ // Wait for the client instance to be spawned, which removes the need to check for two NetworkVariableDeltaMessages
180+ yield return WaitForConditionOrTimeOut ( ( ) => CheckForClientInstance < WorkingUserNetworkVariableComponentUsingExtensionMethod > ( ) ) ;
181+ AssertOnTimeout ( $ "Timed out waiting for the client side object to spawn!") ;
128182
129- serverNetworkObject . GetComponent < WorkingUserNetworkVariableComponentUsingExtensionMethod > ( ) . NetworkVariable . Value = new MyTypeTwo { Value = 20 } ;
183+ // Get server and client instances of the test component
184+ var clientInstance = WorkingUserNetworkVariableComponentBase . GetRelativeInstance < WorkingUserNetworkVariableComponentUsingExtensionMethod > ( m_ClientNetworkManagers [ 0 ] . LocalClientId ) ;
185+ var serverInstance = serverNetworkObject . GetComponent < WorkingUserNetworkVariableComponentUsingExtensionMethod > ( ) ;
186+ // Set the server side value
187+ serverInstance . NetworkVariable . Value = new MyTypeTwo { Value = 20 } ;
130188
189+ // Wait for the NetworkVariableDeltaMessage
131190 yield return NetcodeIntegrationTestHelpers . WaitForMessageOfTypeReceived < NetworkVariableDeltaMessage > ( m_ClientNetworkManagers [ 0 ] ) ;
132- yield return NetcodeIntegrationTestHelpers . WaitForMessageOfTypeReceived < NetworkVariableDeltaMessage > ( m_ClientNetworkManagers [ 0 ] ) ;
133-
134- var clientObject = GetComponentForClient < WorkingUserNetworkVariableComponentUsingExtensionMethod > ( m_ClientNetworkManagers [ 0 ] . LocalClientId ) ;
135191
136- Assert . AreEqual ( serverNetworkObject . GetComponent < WorkingUserNetworkVariableComponentUsingExtensionMethod > ( ) . NetworkVariable . Value . Value , clientObject . NetworkVariable . Value . Value ) ;
137- Assert . AreEqual ( 20 , clientObject . NetworkVariable . Value . Value ) ;
192+ // Wait for the client side value to be updated to the server side value (can take an additional frame)
193+ yield return WaitForConditionOrTimeOut ( ( ) => clientInstance . NetworkVariable . Value . Value == serverInstance . NetworkVariable . Value . Value ) ;
194+ AssertOnTimeout ( $ "Timed out waiting for the client side object's value ({ clientInstance . NetworkVariable . Value . Value } ) to equal the server side objects value ({ serverInstance . NetworkVariable . Value . Value } )!") ;
195+ Assert . AreEqual ( serverInstance . NetworkVariable . Value . Value , clientInstance . NetworkVariable . Value . Value ) ;
196+ Assert . AreEqual ( 20 , clientInstance . NetworkVariable . Value . Value ) ;
138197 }
139198
140199 [ Test ]
0 commit comments