@@ -18,6 +18,12 @@ internal class NetworkObjectDontDestroyWithOwnerTests : NetcodeIntegrationTest
18
18
private const int k_NumberObjectsToSpawn = 16 ;
19
19
protected override int NumberOfClients => 3 ;
20
20
21
+ public enum ParentedPass
22
+ {
23
+ NoParent ,
24
+ HasParent
25
+ }
26
+
21
27
protected GameObject m_DestroyWithOwnerPrefab ;
22
28
protected GameObject m_DontDestroyWithOwnerPrefab ;
23
29
protected GameObject m_PrefabNoObserversSpawn ;
@@ -95,6 +101,63 @@ private void SpawnAllObjects(bool dontDestroyWithOwner)
95
101
}
96
102
}
97
103
104
+ /// <summary>
105
+ /// Validates that the dont destroy with owner object is parented under
106
+ /// the destroy with owner object.
107
+ /// </summary>
108
+ private bool HaveAllObjectInstancesParented ( StringBuilder errorLog )
109
+ {
110
+ foreach ( var networkManager in m_NetworkManagers )
111
+ {
112
+ var relativeSpawnedObjects = networkManager . SpawnManager . SpawnedObjects ;
113
+ for ( int i = 0 ; i < k_NumberObjectsToSpawn ; i ++ )
114
+ {
115
+ var dontDestroyObjectId = m_DontDestroyObjectIds [ i ] ;
116
+ var destroyObjectId = m_DestroyObjectIds [ i ] ;
117
+ var dontDestroyObject = ( NetworkObject ) null ;
118
+ var destroyObject = ( NetworkObject ) null ;
119
+ if ( ! relativeSpawnedObjects . ContainsKey ( dontDestroyObjectId ) )
120
+ {
121
+ errorLog . AppendLine ( $ "[Client-{ networkManager . LocalClientId } ][DontDestroyWithOwner] Has not spawned { nameof ( NetworkObject ) } -{ dontDestroyObjectId } !") ;
122
+ }
123
+ else
124
+ {
125
+ dontDestroyObject = relativeSpawnedObjects [ dontDestroyObjectId ] ;
126
+ }
127
+ if ( ! relativeSpawnedObjects . ContainsKey ( destroyObjectId ) )
128
+ {
129
+ errorLog . AppendLine ( $ "[Client-{ networkManager . LocalClientId } ][DestroyWithOwner] Has not spawned { nameof ( NetworkObject ) } -{ destroyObjectId } !") ;
130
+ }
131
+ else
132
+ {
133
+ destroyObject = relativeSpawnedObjects [ destroyObjectId ] ;
134
+ }
135
+
136
+ if ( dontDestroyObject != null && destroyObject != null && dontDestroyObject . transform . parent != destroyObject . transform )
137
+ {
138
+ errorLog . AppendLine ( $ "[Client-{ networkManager . LocalClientId } ][Not Parented] { destroyObject . name } is not parented under { dontDestroyObject . name } !") ;
139
+ }
140
+ }
141
+ }
142
+ return errorLog . Length == 0 ;
143
+ }
144
+
145
+ /// <summary>
146
+ /// Parents the dont destroy with owner objects under the destroy with owner objects for the parenting portion of the test.
147
+ /// </summary>
148
+ private void ParentObjects ( )
149
+ {
150
+ var networkManager = ! m_DistributedAuthority ? GetAuthorityNetworkManager ( ) : m_NetworkManagers . Where ( ( c ) => c . LocalClientId == m_NonAuthorityClientId ) . First ( ) ;
151
+ for ( int i = 0 ; i < k_NumberObjectsToSpawn ; i ++ )
152
+ {
153
+ var dontDestroyObjectId = m_DontDestroyObjectIds [ i ] ;
154
+ var destroyObjectId = m_DestroyObjectIds [ i ] ;
155
+ var dontDestroyObject = networkManager . SpawnManager . SpawnedObjects [ dontDestroyObjectId ] ;
156
+ var destroyObject = networkManager . SpawnManager . SpawnedObjects [ destroyObjectId ] ;
157
+ Assert . IsTrue ( dontDestroyObject . TrySetParent ( destroyObject ) , $ "[Client-{ networkManager . LocalClientId } ][Parent Failure] Could not parent { destroyObject . name } under { dontDestroyObject . name } !") ;
158
+ }
159
+ }
160
+
98
161
/// <summary>
99
162
/// Validates that the non-authority owner client disconnection
100
163
/// was registered on all clients.
@@ -144,13 +207,39 @@ private bool ValidateDontDestroyWithOwner(StringBuilder errorLog)
144
207
return errorLog . Length == 0 ;
145
208
}
146
209
210
+ /// <summary>
211
+ /// The primary parented validation for the <see cref="DontDestroyWithOwnerTest"/>.
212
+ /// This validates that:
213
+ /// - Spawned objects that are set to destroy with the owner gets destroyed/despawned when the owning client disconnects.
214
+ /// - Spawned objects that are set to not destroy with the owner and parented under a spawned object set to destroy with owner that
215
+ /// the objects that are set to not destroy with the owner are not destroyed/despawned when the owning client disconnects.
216
+ /// </summary>
217
+ private bool ValidateParentedDontDestroyWithOwnerId ( StringBuilder errorLog )
218
+ {
219
+ foreach ( var networkManager in m_NetworkManagers )
220
+ {
221
+ var relativeSpawnedObjects = networkManager . SpawnManager . SpawnedObjects ;
222
+ for ( int i = 0 ; i < k_NumberObjectsToSpawn ; i ++ )
223
+ {
224
+ var dontDestroyObjectId = m_DontDestroyObjectIds [ i ] ;
225
+ var dontDestroyObjectOwnerId = relativeSpawnedObjects [ dontDestroyObjectId ] . OwnerClientId ;
226
+
227
+ if ( dontDestroyObjectOwnerId == m_NonAuthorityClientId )
228
+ {
229
+ errorLog . AppendLine ( $ "[Client-{ networkManager . LocalClientId } ][DontDestroyWithOwner][!Owner!] { nameof ( NetworkObject ) } -{ dontDestroyObjectId } should not still belong to Client-{ m_NonAuthorityClientId } !") ;
230
+ }
231
+ }
232
+ }
233
+ return errorLog . Length == 0 ;
234
+ }
235
+
147
236
/// <summary>
148
237
/// This validates that:
149
238
/// - Spawned objects that are set to destroy with the owner gets destroyed/despawned when the owning client disconnects.
150
239
/// - Spawned objects that are set to not destroy with the owner are not destroyed/despawned when the owning client disconnects.
151
240
/// </summary>
152
241
[ UnityTest ]
153
- public IEnumerator DontDestroyWithOwnerTest ( )
242
+ public IEnumerator DontDestroyWithOwnerTest ( [ Values ] ParentedPass parentedPass )
154
243
{
155
244
var authority = GetAuthorityNetworkManager ( ) ;
156
245
var nonAuthority = GetNonAuthorityNetworkManager ( ) ;
@@ -164,13 +253,26 @@ public IEnumerator DontDestroyWithOwnerTest()
164
253
yield return WaitForConditionOrTimeOut ( HaveAllObjectInstancesSpawned ) ;
165
254
AssertOnTimeout ( $ "Timed out waiting for all clients to spawn objects!") ;
166
255
256
+ if ( parentedPass == ParentedPass . HasParent )
257
+ {
258
+ ParentObjects ( ) ;
259
+ yield return WaitForConditionOrTimeOut ( HaveAllObjectInstancesParented ) ;
260
+ AssertOnTimeout ( $ "Timed out waiting for all DontDestroy objects to be parented under the Destroy objects!") ;
261
+ }
262
+
167
263
yield return StopOneClient ( nonAuthority ) ;
168
264
169
265
yield return WaitForConditionOrTimeOut ( NonAuthorityHasDisconnected ) ;
170
266
AssertOnTimeout ( $ "Timed out waiting for all clients to register that Client-{ m_NonAuthorityClientId } has disconnected!") ;
171
267
172
268
yield return WaitForConditionOrTimeOut ( ValidateDontDestroyWithOwner ) ;
173
- AssertOnTimeout ( $ "Timed out while validating the DontDestroyWithOwnerTest results!") ;
269
+ AssertOnTimeout ( $ "Timed out while validating the base-line DontDestroyWithOwnerTest results!") ;
270
+
271
+ if ( parentedPass == ParentedPass . HasParent )
272
+ {
273
+ yield return WaitForConditionOrTimeOut ( ValidateParentedDontDestroyWithOwnerId ) ;
274
+ AssertOnTimeout ( $ "Timed out while validating the parented don't destroy objects do not still belong to disconnected Client-{ m_NonAuthorityClientId } !") ;
275
+ }
174
276
}
175
277
176
278
[ UnityTest ]
0 commit comments