2
2
using System . Collections . Generic ;
3
3
using System . Linq ;
4
4
using NUnit . Framework ;
5
+ using Unity . Netcode . Components ;
5
6
using Unity . Netcode . TestHelpers . Runtime ;
6
7
using UnityEngine ;
7
8
using UnityEngine . TestTools ;
@@ -23,11 +24,23 @@ public override void OnGainedOwnership()
23
24
OnGainedOwnershipFired = true ;
24
25
}
25
26
27
+ protected override void OnOwnershipChanged ( ulong previous , ulong current )
28
+ {
29
+ Assert . True ( previous != current , $ "[{ nameof ( OnOwnershipChanged ) } ][Invalid Parameters] Invoked and the previous ({ previous } ) equals the current ({ current } )!") ;
30
+ base . OnOwnershipChanged ( previous , current ) ;
31
+ }
32
+
26
33
public void ResetFlags ( )
27
34
{
28
35
OnLostOwnershipFired = false ;
29
36
OnGainedOwnershipFired = false ;
30
37
}
38
+
39
+ [ Rpc ( SendTo . Server ) ]
40
+ public void ChangeOwnershipRpc ( RpcParams rpcParams = default )
41
+ {
42
+ NetworkObject . ChangeOwnership ( rpcParams . Receive . SenderClientId ) ;
43
+ }
31
44
}
32
45
33
46
[ TestFixture ( HostOrServer . Host ) ]
@@ -52,6 +65,7 @@ protected override void OnServerAndClientsCreated()
52
65
{
53
66
m_OwnershipPrefab = CreateNetworkObjectPrefab ( "OnwershipPrefab" ) ;
54
67
m_OwnershipPrefab . AddComponent < NetworkObjectOwnershipComponent > ( ) ;
68
+ m_OwnershipPrefab . AddComponent < NetworkTransform > ( ) ;
55
69
base . OnServerAndClientsCreated ( ) ;
56
70
}
57
71
@@ -358,5 +372,75 @@ public IEnumerator TestOwnedObjectCounts()
358
372
AssertOnTimeout ( $ "Server does not have the correct count for all clients spawned { k_NumberOfSpawnedObjects } { nameof ( NetworkObject ) } s!") ;
359
373
360
374
}
375
+
376
+ /// <summary>
377
+ /// Validates that when changing ownership NetworkTransform does not enter into a bad state
378
+ /// because the previous and current owner identifiers are the same. For client-server this
379
+ /// ends up always being the server, but for distributed authority the authority changes when
380
+ /// ownership changes.
381
+ /// </summary>
382
+ [ UnityTest ]
383
+ public IEnumerator TestAuthorityChangingOwnership ( )
384
+ {
385
+ var authorityManager = m_ServerNetworkManager ; ;
386
+ var allNetworkManagers = m_ClientNetworkManagers . ToList ( ) ;
387
+ allNetworkManagers . Add ( m_ServerNetworkManager ) ;
388
+
389
+ m_OwnershipObject = SpawnObject ( m_OwnershipPrefab , m_ServerNetworkManager ) ;
390
+ m_OwnershipNetworkObject = m_OwnershipObject . GetComponent < NetworkObject > ( ) ;
391
+ var ownershipNetworkObjectId = m_OwnershipNetworkObject . NetworkObjectId ;
392
+ bool WaitForClientsToSpawnNetworkObject ( )
393
+ {
394
+ foreach ( var clientNetworkManager in m_ClientNetworkManagers )
395
+ {
396
+ if ( ! clientNetworkManager . SpawnManager . SpawnedObjects . ContainsKey ( ownershipNetworkObjectId ) )
397
+ {
398
+ return false ;
399
+ }
400
+ }
401
+ return true ;
402
+ }
403
+
404
+ yield return WaitForConditionOrTimeOut ( WaitForClientsToSpawnNetworkObject ) ;
405
+ AssertOnTimeout ( $ "Timed out waiting for all clients to spawn the { m_OwnershipNetworkObject . name } { nameof ( NetworkObject ) } instance!") ;
406
+
407
+ var currentTargetOwner = ( ulong ) 0 ;
408
+ bool WaitForAllInstancesToChangeOwnership ( )
409
+ {
410
+ foreach ( var clientNetworkManager in m_ClientNetworkManagers )
411
+ {
412
+ if ( ! clientNetworkManager . SpawnManager . SpawnedObjects . ContainsKey ( ownershipNetworkObjectId ) )
413
+ {
414
+ return false ;
415
+ }
416
+ if ( clientNetworkManager . SpawnManager . SpawnedObjects [ ownershipNetworkObjectId ] . OwnerClientId != currentTargetOwner )
417
+ {
418
+ return false ;
419
+ }
420
+ }
421
+ return true ;
422
+ }
423
+
424
+ // Change ownership a few times and as long as the previous and current owners are not the same when
425
+ // OnOwnershipChanged is invoked then the test passed.
426
+ foreach ( var networkManager in allNetworkManagers )
427
+ {
428
+ if ( networkManager == authorityManager )
429
+ {
430
+ continue ;
431
+ }
432
+ var clonedObject = networkManager . SpawnManager . SpawnedObjects [ ownershipNetworkObjectId ] ;
433
+
434
+ if ( clonedObject . OwnerClientId == networkManager . LocalClientId )
435
+ {
436
+ continue ;
437
+ }
438
+
439
+ var testComponent = clonedObject . GetComponent < NetworkObjectOwnershipComponent > ( ) ;
440
+ testComponent . ChangeOwnershipRpc ( ) ;
441
+ yield return WaitForAllInstancesToChangeOwnership ( ) ;
442
+ AssertOnTimeout ( $ "Timed out waiting for all instances to change ownership to Client-{ networkManager . LocalClientId } !") ;
443
+ }
444
+ }
361
445
}
362
446
}
0 commit comments