Skip to content

Commit a7551b4

Browse files
test
Did a bit of an overhaul on the original NetworkRigidbodyTest. It should now run with distributed authority tests and includes a 2D rigidbody in the tests as well.
1 parent bb9ff76 commit a7551b4

1 file changed

Lines changed: 178 additions & 64 deletions

File tree

com.unity.netcode.gameobjects/Tests/Runtime/Physics/NetworkRigidbodyTest.cs

Lines changed: 178 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -10,104 +10,218 @@
1010

1111
namespace Unity.Netcode.RuntimeTests
1212
{
13-
[TestFixture(RigidbodyInterpolation.Interpolate, true, true)] // This should be allowed under all condistions when using Rigidbody motion
14-
[TestFixture(RigidbodyInterpolation.Extrapolate, true, true)] // This should not allow extrapolation on non-auth instances when using Rigidbody motion & NT interpolation
15-
[TestFixture(RigidbodyInterpolation.Extrapolate, false, true)] // This should allow extrapolation on non-auth instances when using Rigidbody & NT has no interpolation
16-
[TestFixture(RigidbodyInterpolation.Interpolate, true, false)] // This should not allow kinematic instances to have Rigidbody interpolation enabled
17-
[TestFixture(RigidbodyInterpolation.Interpolate, false, false)] // Testing that rigid body interpolation remains the same if NT interpolate is disabled
13+
[TestFixture(HostOrServer.Server)]
14+
[TestFixture(HostOrServer.Host)]
15+
[TestFixture(HostOrServer.DAHost)]
1816
internal class NetworkRigidbodyTest : NetcodeIntegrationTest
1917
{
2018
protected override int NumberOfClients => 1;
21-
private bool m_NetworkTransformInterpolate;
22-
private bool m_UseRigidBodyForMotion;
23-
private RigidbodyInterpolation m_RigidbodyInterpolation;
2419

25-
public NetworkRigidbodyTest(RigidbodyInterpolation rigidbodyInterpolation, bool networkTransformInterpolate, bool useRigidbodyForMotion)
20+
private List<(RigidbodyInterpolation interpolationType, bool enableInterpolation, bool useRigidbodyForMotion)> m_TestConfigurations =
21+
new List<(RigidbodyInterpolation interpolationType, bool enableInterpolation, bool useRigidbodyForMotion)>()
22+
{
23+
(RigidbodyInterpolation.Interpolate, true, true), // This should be allowed under all condistions when using Rigidbody motion
24+
(RigidbodyInterpolation.Extrapolate, true, true), // This should not allow extrapolation on non-auth instances when using Rigidbody motion & NT interpolation
25+
(RigidbodyInterpolation.Extrapolate, false, true), // This should allow extrapolation on non-auth instances when using Rigidbody & NT has no interpolation
26+
(RigidbodyInterpolation.Interpolate, true, false), // This should not allow kinematic instances to have Rigidbody interpolation enabled
27+
(RigidbodyInterpolation.Interpolate, false, false) // Testing that rigidbody interpolation remains the same if NT interpolate is disabled
28+
};
29+
30+
/// <summary>
31+
/// The current test configuration applied to the current test running.
32+
/// </summary>
33+
private (RigidbodyInterpolation interpolationType, bool enableInterpolation, bool useRigidbodyForMotion) m_CurrentConfiguration;
34+
35+
public NetworkRigidbodyTest(HostOrServer hostOrServer) : base(hostOrServer)
2636
{
27-
m_RigidbodyInterpolation = rigidbodyInterpolation;
28-
m_NetworkTransformInterpolate = networkTransformInterpolate;
29-
m_UseRigidBodyForMotion = useRigidbodyForMotion;
3037
}
3138

32-
protected override void OnCreatePlayerPrefab()
39+
/// <summary>
40+
/// Base prefab for <see cref="Rigidbody"/> and <see cref="NetworkRigidbody"/>
41+
/// </summary>
42+
private GameObject m_RigidbodyPrefab;
43+
private NetworkTransform m_3DNetworkTransform;
44+
private Rigidbody m_PrefabRigidbody;
45+
private NetworkRigidbody m_PrefabNetworkRigidbody;
46+
private NetworkObject m_3DAuthorityInstance;
47+
48+
/// <summary>
49+
/// Base prefab for <see cref="Rigidbody2D"/> and <see cref="NetworkRigidbody2D"/>
50+
/// </summary>
51+
private GameObject m_Rigidbody2DPrefab;
52+
private NetworkTransform m_2DNetworkTransform;
53+
private Rigidbody2D m_PrefabRigidbody2D;
54+
private NetworkRigidbody2D m_PrefabNetworkRigidbody2D;
55+
private NetworkObject m_2DAuthorityInstance;
56+
57+
protected override void OnServerAndClientsCreated()
3358
{
34-
var networkTransform = m_PlayerPrefab.AddComponent<NetworkTransform>();
35-
networkTransform.Interpolate = m_NetworkTransformInterpolate;
36-
var rigidbody = m_PlayerPrefab.AddComponent<Rigidbody>();
37-
rigidbody.interpolation = m_RigidbodyInterpolation;
38-
var networkRigidbody = m_PlayerPrefab.AddComponent<NetworkRigidbody>();
39-
networkRigidbody.UseRigidBodyForMotion = m_UseRigidBodyForMotion;
59+
m_RigidbodyPrefab = CreateNetworkObjectPrefab("RBTest");
60+
m_3DNetworkTransform = m_RigidbodyPrefab.AddComponent<NetworkTransform>();
61+
m_PrefabRigidbody = m_RigidbodyPrefab.AddComponent<Rigidbody>();
62+
m_PrefabNetworkRigidbody = m_RigidbodyPrefab.AddComponent<NetworkRigidbody>();
63+
64+
m_Rigidbody2DPrefab = CreateNetworkObjectPrefab("RB2DTest");
65+
m_2DNetworkTransform = m_Rigidbody2DPrefab.AddComponent<NetworkTransform>();
66+
m_PrefabRigidbody2D = m_Rigidbody2DPrefab.AddComponent<Rigidbody2D>();
67+
m_PrefabNetworkRigidbody2D = m_Rigidbody2DPrefab.AddComponent<NetworkRigidbody2D>();
68+
69+
base.OnServerAndClientsCreated();
70+
}
71+
72+
private string m_ConfigHeader;
73+
private void ApplyCurrentTestConfiguration()
74+
{
75+
// Configure both 3D and 2D versions based on the current test configuration
76+
m_3DNetworkTransform.Interpolate = m_CurrentConfiguration.enableInterpolation;
77+
m_PrefabRigidbody.interpolation = m_CurrentConfiguration.interpolationType;
78+
m_PrefabNetworkRigidbody.UseRigidBodyForMotion = m_CurrentConfiguration.useRigidbodyForMotion;
79+
m_2DNetworkTransform.Interpolate = m_CurrentConfiguration.enableInterpolation;
80+
m_PrefabRigidbody2D.interpolation = m_CurrentConfiguration.interpolationType == RigidbodyInterpolation.Interpolate ? RigidbodyInterpolation2D.Interpolate : RigidbodyInterpolation2D.Extrapolate;
81+
m_PrefabNetworkRigidbody2D.UseRigidBodyForMotion = m_CurrentConfiguration.useRigidbodyForMotion;
82+
83+
// Build a header used in assert messages
84+
m_ConfigHeader = $"[{m_CurrentConfiguration.interpolationType}][Interpolate: {m_CurrentConfiguration.enableInterpolation}][RB-Motion: {m_CurrentConfiguration.useRigidbodyForMotion}]";
4085
}
4186

4287
/// <summary>
43-
/// Tests that a server can destroy a NetworkObject and that it gets despawned correctly.
88+
/// Iterates through the <see cref="m_TestConfigurations"/> to validate various
89+
/// Rigidbody interpolation settings and kinematic states for authority and non-authority
90+
/// instances.
4491
/// </summary>
45-
/// <returns></returns>
4692
[UnityTest]
4793
public IEnumerator TestRigidbodyKinematicEnableDisable()
4894
{
49-
// This is the *SERVER VERSION* of the *CLIENT PLAYER*
50-
var serverClientPlayerInstance = m_ServerNetworkManager.ConnectedClients[m_ClientNetworkManagers[0].LocalClientId].PlayerObject;
95+
foreach (var configuration in m_TestConfigurations)
96+
{
97+
m_CurrentConfiguration = configuration;
98+
ApplyCurrentTestConfiguration();
99+
yield return RunTestConfiguration();
100+
}
101+
}
51102

52-
// This is the *CLIENT VERSION* of the *CLIENT PLAYER*
53-
var clientPlayerInstance = m_ClientNetworkManagers[0].LocalClient.PlayerObject;
103+
/// <summary>
104+
/// Validates the current applied test configuration.
105+
/// </summary>
106+
private IEnumerator RunTestConfiguration()
107+
{
108+
var authority = GetAuthorityNetworkManager();
109+
var nonAuthority = GetNonAuthorityNetworkManager();
54110

55-
Assert.IsNotNull(serverClientPlayerInstance, $"{nameof(serverClientPlayerInstance)} is null!");
56-
Assert.IsNotNull(clientPlayerInstance, $"{nameof(clientPlayerInstance)} is null!");
111+
// Spawn instances of both the 3D and 2D prefabs configured for the current test.
112+
m_3DAuthorityInstance = SpawnObject(m_RigidbodyPrefab, authority).GetComponent<NetworkObject>();
113+
yield return WaitForSpawnedOnAllOrTimeOut(m_3DAuthorityInstance);
114+
AssertOnTimeout($"Failed to spawn {m_3DAuthorityInstance.name} on all clients!");
115+
116+
m_2DAuthorityInstance = SpawnObject(m_Rigidbody2DPrefab, authority).GetComponent<NetworkObject>();
117+
yield return WaitForSpawnedOnAllOrTimeOut(m_2DAuthorityInstance);
118+
AssertOnTimeout($"Failed to spawn {m_2DAuthorityInstance.name} on all clients!");
119+
120+
// Test 3D Rigidbody
121+
#region 3D Rigidbody validation
122+
var authorityRigidbody = m_3DAuthorityInstance.GetComponent<Rigidbody>();
123+
var nonAuthorityInstance = nonAuthority.SpawnManager.SpawnedObjects[m_3DAuthorityInstance.NetworkObjectId];
124+
var nonAuthorityRigidbody = nonAuthorityInstance.GetComponent<Rigidbody>();
125+
var authorityHeader = $"{m_ConfigHeader}[Authority] Client-{authority.LocalClientId}'s instance of {m_3DAuthorityInstance.name}";
126+
// The authority instance should always be non-kinematic
127+
Assert.False(authorityRigidbody.isKinematic, $"{authorityHeader} is kinematic!");
128+
129+
var nonAuthorityHeader = $"{m_ConfigHeader}[Non-Authority] Client-{nonAuthority.LocalClientId}'s instance of {nonAuthorityInstance.name}";
130+
// Non-authority instances should always be kinematic
131+
Assert.True(nonAuthorityRigidbody.isKinematic, $"{nonAuthorityHeader} is not kinematic!");
132+
var interpolateCompareNonAuthoritative = RigidbodyInterpolation.None;
133+
134+
if (m_CurrentConfiguration.useRigidbodyForMotion)
135+
{
136+
// The authoritative instance can be None, Interpolate, or Extrapolate for the Rigidbody interpolation settings.
137+
Assert.AreEqual(m_CurrentConfiguration.interpolationType, authorityRigidbody.interpolation, $"{authorityHeader} interpolation is {authorityRigidbody.interpolation} " +
138+
$"and not {m_CurrentConfiguration.interpolationType}!");
57139

58-
var serverClientInstanceRigidBody = serverClientPlayerInstance.GetComponent<Rigidbody>();
59-
var clientRigidBody = clientPlayerInstance.GetComponent<Rigidbody>();
140+
// When using Rigidbody motion, authoritative and non-authoritative Rigidbody interpolation settings should be preserved (except when extrapolation is used
141+
interpolateCompareNonAuthoritative = m_CurrentConfiguration.enableInterpolation ? RigidbodyInterpolation.Interpolate : m_CurrentConfiguration.interpolationType;
60142

61-
if (m_UseRigidBodyForMotion)
143+
}
144+
else
62145
{
63-
var interpolateCompareNonAuthoritative = m_NetworkTransformInterpolate ? RigidbodyInterpolation.Interpolate : m_RigidbodyInterpolation;
146+
Assert.AreEqual(RigidbodyInterpolation.Interpolate, authorityRigidbody.interpolation, $"{authorityHeader} interpolation is {authorityRigidbody.interpolation} " +
147+
$"and not {RigidbodyInterpolation.Interpolate}!");
64148

65-
// Server authoritative NT should yield non-kinematic mode for the server-side player instance
66-
Assert.False(serverClientInstanceRigidBody.isKinematic, $"[Server-Side] Client-{m_ClientNetworkManagers[0].LocalClientId} player's {nameof(Rigidbody)} is kinematic!");
149+
// client rigidbody has no authority with NT interpolation disabled should allow Rigidbody interpolation
150+
interpolateCompareNonAuthoritative = m_CurrentConfiguration.enableInterpolation ? RigidbodyInterpolation.None : RigidbodyInterpolation.Interpolate;
151+
}
67152

153+
Assert.AreEqual(interpolateCompareNonAuthoritative, nonAuthorityRigidbody.interpolation, $"{nonAuthorityHeader} interpolation is {nonAuthorityRigidbody.interpolation} " +
154+
$"and not {interpolateCompareNonAuthoritative}!");
155+
#endregion
156+
157+
// Test 2D Rigidbody
158+
#region 2D Rigidbody validation
159+
var authorityRigidbody2D = m_2DAuthorityInstance.GetComponent<Rigidbody2D>();
160+
var nonAuthorityInstance2D = nonAuthority.SpawnManager.SpawnedObjects[m_2DAuthorityInstance.NetworkObjectId];
161+
var nonAuthorityRigidbody2D = nonAuthorityInstance2D.GetComponent<Rigidbody2D>();
162+
163+
authorityHeader = $"{m_ConfigHeader}[Authority] Client-{authority.LocalClientId}'s instance of {m_2DAuthorityInstance.name}";
164+
// The authority instance should always be non-kinematic
165+
Assert.False(authorityRigidbody2D.bodyType == RigidbodyType2D.Kinematic, $"{authorityHeader} is kinematic!");
166+
167+
nonAuthorityHeader = $"{m_ConfigHeader}[Non-Authority] Client-{nonAuthority.LocalClientId}'s instance of {nonAuthorityInstance.name}";
168+
// Non-authority instances should always be kinematic
169+
Assert.True(nonAuthorityRigidbody2D.bodyType == RigidbodyType2D.Kinematic, $"{nonAuthorityHeader} is not kinematic!");
170+
var interpolateCompareNonAuthoritative2D = RigidbodyInterpolation2D.None;
171+
var configInterpolation2D = m_CurrentConfiguration.interpolationType == RigidbodyInterpolation.Interpolate ? RigidbodyInterpolation2D.Interpolate : RigidbodyInterpolation2D.Extrapolate;
172+
if (m_CurrentConfiguration.useRigidbodyForMotion)
173+
{
68174
// The authoritative instance can be None, Interpolate, or Extrapolate for the Rigidbody interpolation settings.
69-
Assert.AreEqual(m_RigidbodyInterpolation, serverClientInstanceRigidBody.interpolation, $"[Server-Side] Client-{m_ClientNetworkManagers[0].LocalClientId} " +
70-
$"player's {nameof(Rigidbody)}'s interpolation is {serverClientInstanceRigidBody.interpolation} and not {m_RigidbodyInterpolation}!");
71-
72-
// Server authoritative NT should yield kinematic mode for the client-side player instance
73-
Assert.True(clientRigidBody.isKinematic, $"[Client-Side] Client-{m_ClientNetworkManagers[0].LocalClientId} player's {nameof(Rigidbody)} is not kinematic!");
175+
Assert.AreEqual(configInterpolation2D, authorityRigidbody2D.interpolation, $"{authorityHeader} interpolation is {authorityRigidbody2D.interpolation} " +
176+
$"and not {m_CurrentConfiguration.interpolationType}!");
74177

75178
// When using Rigidbody motion, authoritative and non-authoritative Rigidbody interpolation settings should be preserved (except when extrapolation is used
76-
Assert.AreEqual(interpolateCompareNonAuthoritative, clientRigidBody.interpolation, $"[Client-Side] Client-{m_ClientNetworkManagers[0].LocalClientId} " +
77-
$"player's {nameof(Rigidbody)}'s interpolation is {clientRigidBody.interpolation} and not {interpolateCompareNonAuthoritative}!");
179+
interpolateCompareNonAuthoritative2D = m_CurrentConfiguration.enableInterpolation ? RigidbodyInterpolation2D.Interpolate : configInterpolation2D;
78180
}
79181
else
80182
{
81-
// server rigidbody has authority and should not be kinematic
82-
Assert.False(serverClientInstanceRigidBody.isKinematic, $"[Server-Side] Client-{m_ClientNetworkManagers[0].LocalClientId} player's {nameof(Rigidbody)} is kinematic!");
83-
Assert.AreEqual(RigidbodyInterpolation.Interpolate, serverClientInstanceRigidBody.interpolation, $"[Server-Side] Client-{m_ClientNetworkManagers[0].LocalClientId} " +
84-
$"player's {nameof(Rigidbody)}'s interpolation is {serverClientInstanceRigidBody.interpolation} and not {nameof(RigidbodyInterpolation.Interpolate)}!");
85-
86-
// Server authoritative NT should yield kinematic mode for the client-side player instance
87-
Assert.True(clientRigidBody.isKinematic, $"[Client-Side] Client-{m_ClientNetworkManagers[0].LocalClientId} player's {nameof(Rigidbody)} is not kinematic!");
183+
Assert.AreEqual(RigidbodyInterpolation2D.Interpolate, authorityRigidbody2D.interpolation, $"{authorityHeader} interpolation is {authorityRigidbody2D.interpolation} " +
184+
$"and not {RigidbodyInterpolation2D.Interpolate}!");
88185

89186
// client rigidbody has no authority with NT interpolation disabled should allow Rigidbody interpolation
90-
if (!m_NetworkTransformInterpolate)
91-
{
92-
Assert.AreEqual(RigidbodyInterpolation.Interpolate, clientRigidBody.interpolation, $"[Client-Side] Client-{m_ClientNetworkManagers[0].LocalClientId} " +
93-
$"player's {nameof(Rigidbody)}'s interpolation is {clientRigidBody.interpolation} and not {nameof(RigidbodyInterpolation.Interpolate)}!");
94-
}
95-
else
96-
{
97-
Assert.AreEqual(RigidbodyInterpolation.None, clientRigidBody.interpolation, $"[Client-Side] Client-{m_ClientNetworkManagers[0].LocalClientId} " +
98-
$"player's {nameof(Rigidbody)}'s interpolation is {clientRigidBody.interpolation} and not {nameof(RigidbodyInterpolation.None)}!");
99-
}
187+
interpolateCompareNonAuthoritative2D = m_CurrentConfiguration.enableInterpolation ? RigidbodyInterpolation2D.None : RigidbodyInterpolation2D.Interpolate;
100188
}
101189

102-
// despawn the server player (but keep it around on the server)
103-
serverClientPlayerInstance.Despawn(false);
190+
Assert.AreEqual(interpolateCompareNonAuthoritative2D, nonAuthorityRigidbody2D.interpolation, $"{nonAuthorityHeader} interpolation is {nonAuthorityRigidbody2D.interpolation} " +
191+
$"and not {interpolateCompareNonAuthoritative}!");
192+
#endregion
193+
194+
var spawnedInstances = new List<NetworkObject>() { m_3DAuthorityInstance, m_2DAuthorityInstance };
195+
m_3DAuthorityInstance.Despawn();
196+
m_2DAuthorityInstance.Despawn();
197+
yield return WaitForDespawnedOnAllOrTimeOut(spawnedInstances);
198+
AssertOnTimeout($"Failed to de-spawn instances on all clients!");
199+
m_3DAuthorityInstance = null;
200+
m_2DAuthorityInstance = null;
201+
}
104202

105-
yield return WaitForConditionOrTimeOut(() => !serverClientPlayerInstance.IsSpawned && !clientPlayerInstance.IsSpawned);
106-
AssertOnTimeout("Timed out waiting for client player to despawn on both server and client!");
203+
/// <summary>
204+
/// Handle clean up in case of a failed test
205+
/// </summary>
206+
protected override IEnumerator OnTearDown()
207+
{
208+
// If either of these are not null then we most likely failed and didn't cleanup.
107209

108-
// When despawned, we should always be kinematic (i.e. don't apply physics when despawned)
109-
Assert.True(serverClientInstanceRigidBody.isKinematic, $"[Server-Side][Despawned] Client-{m_ClientNetworkManagers[0].LocalClientId} player's {nameof(Rigidbody)} is not kinematic when despawned!");
110-
Assert.IsTrue(clientPlayerInstance == null, $"[Client-Side] Player {nameof(NetworkObject)} is not null!");
210+
// Clean-up m_3DAuthorityInstance
211+
if (m_3DAuthorityInstance)
212+
{
213+
Object.Destroy(m_3DAuthorityInstance);
214+
m_3DAuthorityInstance = null;
215+
}
216+
217+
// Clean-up m_2DAuthorityInstance
218+
if (m_2DAuthorityInstance)
219+
{
220+
Object.Destroy(m_2DAuthorityInstance);
221+
m_2DAuthorityInstance = null;
222+
}
223+
224+
return base.OnTearDown();
111225
}
112226
}
113227

0 commit comments

Comments
 (0)