Skip to content

Commit 058fdb5

Browse files
authored
feat: Client networkrigidbody (#1202)
What this does is enabled the existing functionality of NetworkRigidbody to make it work with client authority and hook it up with the incoming CanCommit property of NetworkTransform.
1 parent 40011ed commit 058fdb5

14 files changed

+470
-42
lines changed

com.unity.netcode.gameobjects/Components/NetworkRigidbody.cs

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ namespace Unity.Netcode.Components
1111
public class NetworkRigidbody : NetworkBehaviour
1212
{
1313
private Rigidbody m_Rigidbody;
14+
private NetworkTransform m_NetworkTransform;
1415

1516
private bool m_OriginalKinematic;
1617

@@ -20,25 +21,25 @@ public class NetworkRigidbody : NetworkBehaviour
2021
/// <summary>
2122
/// Gets a bool value indicating whether this <see cref="NetworkRigidbody"/> on this peer currently holds authority.
2223
/// </summary>
23-
internal bool HasAuthority => NetworkManager.IsServer; // TODO update this once we support owner authoritative NetworkTransform.
24+
private bool HasAuthority => m_NetworkTransform.CanCommitToTransform;
2425

2526
private void Awake()
2627
{
2728
m_Rigidbody = GetComponent<Rigidbody>();
29+
m_NetworkTransform = GetComponent<NetworkTransform>();
2830
}
2931

30-
// Currently commented out because it is not needed as authority currently can't change at runtime.
31-
// private void FixedUpdate()
32-
// {
33-
// if (NetworkManager.IsListening)
34-
// {
35-
// if (HasAuthority != m_IsAuthority)
36-
// {
37-
// m_IsAuthority = HasAuthority;
38-
// UpdateRigidbodyKinematicMode();
39-
// }
40-
// }
41-
// }
32+
private void FixedUpdate()
33+
{
34+
if (NetworkManager.IsListening)
35+
{
36+
if (HasAuthority != m_IsAuthority)
37+
{
38+
m_IsAuthority = HasAuthority;
39+
UpdateRigidbodyKinematicMode();
40+
}
41+
}
42+
}
4243

4344
// Puts the rigidbody in a kinematic non-interpolated mode on everyone but the server.
4445
private void UpdateRigidbodyKinematicMode()

com.unity.netcode.gameobjects/Components/NetworkRigidbody2D.cs

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ namespace Unity.Netcode.Components
1111
public class NetworkRigidbody2D : NetworkBehaviour
1212
{
1313
private Rigidbody2D m_Rigidbody;
14+
private NetworkTransform m_NetworkTransform;
1415

1516
private bool m_OriginalKinematic;
1617

@@ -20,25 +21,25 @@ public class NetworkRigidbody2D : NetworkBehaviour
2021
/// <summary>
2122
/// Gets a bool value indicating whether this <see cref="NetworkRigidbody2D"/> on this peer currently holds authority.
2223
/// </summary>
23-
internal bool HasAuthority => NetworkManager.IsServer; // TODO update this once we support owner authoritative NetworkTransform.
24+
private bool HasAuthority => m_NetworkTransform.CanCommitToTransform;
2425

2526
private void Awake()
2627
{
2728
m_Rigidbody = GetComponent<Rigidbody2D>();
29+
m_NetworkTransform = GetComponent<NetworkTransform>();
2830
}
2931

30-
// Currently commented out because it is not needed as authority currently can't change at runtime.
31-
// private void FixedUpdate()
32-
// {
33-
// if (NetworkManager.IsListening)
34-
// {
35-
// if (HasAuthority != m_IsAuthority)
36-
// {
37-
// m_IsAuthority = HasAuthority;
38-
// UpdateRigidbodyKinematicMode();
39-
// }
40-
// }
41-
// }
32+
private void FixedUpdate()
33+
{
34+
if (NetworkManager.IsListening)
35+
{
36+
if (HasAuthority != m_IsAuthority)
37+
{
38+
m_IsAuthority = HasAuthority;
39+
UpdateRigidbodyKinematicMode();
40+
}
41+
}
42+
}
4243

4344
// Puts the rigidbody in a kinematic non-interpolated mode on everyone but the server.
4445
private void UpdateRigidbodyKinematicMode()

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

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,12 @@
66

77
namespace Unity.Netcode.RuntimeTests.Physics
88
{
9-
public class NetworkRigidbody2DDynamicTest : NetworkRigidbodyTestBase
9+
public class NetworkRigidbody2DDynamicTest : NetworkRigidbody2DTestBase
1010
{
1111
public override bool Kinematic => false;
1212
}
1313

14-
public class NetworkRigidbody2DKinematicTest : NetworkRigidbodyTestBase
14+
public class NetworkRigidbody2DKinematicTest : NetworkRigidbody2DTestBase
1515
{
1616
public override bool Kinematic => true;
1717
}
@@ -29,7 +29,7 @@ public override IEnumerator Setup()
2929
{
3030
playerPrefab.AddComponent<NetworkTransform>();
3131
playerPrefab.AddComponent<Rigidbody2D>();
32-
playerPrefab.AddComponent<NetworkRigidbody>();
32+
playerPrefab.AddComponent<NetworkRigidbody2D>();
3333
playerPrefab.GetComponent<Rigidbody2D>().isKinematic = Kinematic;
3434
});
3535
}
@@ -54,8 +54,7 @@ public IEnumerator TestRigidbodyKinematicEnableDisable()
5454
Assert.IsNotNull(serverPlayer);
5555
Assert.IsNotNull(clientPlayer);
5656

57-
int waitFor = Time.frameCount + 2;
58-
yield return new WaitUntil(() => Time.frameCount >= waitFor);
57+
yield return NetworkRigidbodyTestBase.WaitForFrames(5);
5958

6059
// server rigidbody has authority and should have a kinematic mode of false
6160
Assert.True(serverPlayer.GetComponent<Rigidbody2D>().isKinematic == Kinematic);
@@ -66,12 +65,14 @@ public IEnumerator TestRigidbodyKinematicEnableDisable()
6665
// despawn the server player, (but keep it around on the server)
6766
serverPlayer.GetComponent<NetworkObject>().Despawn(false);
6867

69-
yield return null;
68+
yield return NetworkRigidbodyTestBase.WaitForFrames(5);
7069

7170
Assert.IsTrue(serverPlayer.GetComponent<Rigidbody2D>().isKinematic == Kinematic);
7271

73-
yield return null;
72+
yield return NetworkRigidbodyTestBase.WaitForFrames(5);
73+
7474
Assert.IsTrue(clientPlayer == null); // safety check that object is actually despawned.
7575
}
76+
7677
}
7778
}

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

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -54,8 +54,7 @@ public IEnumerator TestRigidbodyKinematicEnableDisable()
5454
Assert.IsNotNull(serverPlayer);
5555
Assert.IsNotNull(clientPlayer);
5656

57-
int waitFor = Time.frameCount + 2;
58-
yield return new WaitUntil(() => Time.frameCount >= waitFor);
57+
yield return WaitForFrames(5);
5958

6059
// server rigidbody has authority and should have a kinematic mode of false
6160
Assert.True(serverPlayer.GetComponent<Rigidbody>().isKinematic == Kinematic);
@@ -66,12 +65,19 @@ public IEnumerator TestRigidbodyKinematicEnableDisable()
6665
// despawn the server player (but keep it around on the server)
6766
serverPlayer.GetComponent<NetworkObject>().Despawn(false);
6867

69-
yield return null;
68+
yield return WaitForFrames(5);
7069

7170
Assert.IsTrue(serverPlayer.GetComponent<Rigidbody>().isKinematic == Kinematic);
7271

73-
yield return null;
72+
yield return WaitForFrames(5);
73+
7474
Assert.IsTrue(clientPlayer == null); // safety check that object is actually despawned.
7575
}
76+
77+
public static IEnumerator WaitForFrames(int count)
78+
{
79+
int nextFrameNumber = Time.frameCount + count;
80+
yield return new WaitUntil(() => Time.frameCount >= nextFrameNumber);
81+
}
7682
}
7783
}

testproject/Assets/Tests/Runtime/Physics.meta

Lines changed: 8 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
// using System.Collections;
2+
// using NUnit.Framework;
3+
// using Unity.Netcode.Components;
4+
// using Unity.Netcode.Samples;
5+
// using UnityEngine;
6+
// using UnityEngine.TestTools;
7+
//
8+
// // Tests for ClientNetworkTransform (CNT) + NetworkRigidbody. This test is in TestProject because it needs access to ClientNetworkTransform
9+
// namespace Unity.Netcode.RuntimeTests.Physics
10+
// {
11+
// public class NetworkRigidbody2DDynamicCntChangeOwnershipTest : NetworkRigidbody2DCntChangeOwnershipTestBase
12+
// {
13+
// public override bool Kinematic => false;
14+
// }
15+
//
16+
// public class NetworkRigidbody2DKinematicCntChangeOwnershipTest : NetworkRigidbody2DCntChangeOwnershipTestBase
17+
// {
18+
// public override bool Kinematic => true;
19+
// }
20+
//
21+
// public abstract class NetworkRigidbody2DCntChangeOwnershipTestBase : BaseMultiInstanceTest
22+
// {
23+
// protected override int NbClients => 1;
24+
//
25+
// public abstract bool Kinematic { get; }
26+
//
27+
// [UnitySetUp]
28+
// public override IEnumerator Setup()
29+
// {
30+
// yield return StartSomeClientsAndServerWithPlayers(true, NbClients, playerPrefab =>
31+
// {
32+
// playerPrefab.AddComponent<ClientNetworkTransform>();
33+
// playerPrefab.AddComponent<Rigidbody2D>();
34+
// playerPrefab.AddComponent<NetworkRigidbody2D>();
35+
// playerPrefab.GetComponent<Rigidbody2D>().isKinematic = Kinematic;
36+
// });
37+
// }
38+
// /// <summary>
39+
// /// Tests that a server can destroy a NetworkObject and that it gets despawned correctly.
40+
// /// </summary>
41+
// /// <returns></returns>
42+
// [UnityTest]
43+
// public IEnumerator TestRigidbodyKinematicEnableDisable()
44+
// {
45+
// // This is the *SERVER VERSION* of the *CLIENT PLAYER*
46+
// var serverClientPlayerResult = new MultiInstanceHelpers.CoroutineResultWrapper<NetworkObject>();
47+
// yield return MultiInstanceHelpers.Run(MultiInstanceHelpers.GetNetworkObjectByRepresentation((x => x.IsPlayerObject && x.OwnerClientId == m_ClientNetworkManagers[0].LocalClientId), m_ServerNetworkManager, serverClientPlayerResult));
48+
// var serverPlayer = serverClientPlayerResult.Result.gameObject;
49+
//
50+
// // This is the *CLIENT VERSION* of the *CLIENT PLAYER*
51+
// var clientClientPlayerResult = new MultiInstanceHelpers.CoroutineResultWrapper<NetworkObject>();
52+
// yield return MultiInstanceHelpers.Run(MultiInstanceHelpers.GetNetworkObjectByRepresentation((x => x.IsPlayerObject && x.OwnerClientId == m_ClientNetworkManagers[0].LocalClientId), m_ClientNetworkManagers[0], clientClientPlayerResult));
53+
// var clientPlayer = clientClientPlayerResult.Result.gameObject;
54+
//
55+
// Assert.IsNotNull(serverPlayer);
56+
// Assert.IsNotNull(clientPlayer);
57+
//
58+
// int waitFor = Time.frameCount + 2;
59+
// yield return new WaitUntil(() => Time.frameCount >= waitFor);
60+
//
61+
// TestKinematicSetCorrectly(clientPlayer, serverPlayer);
62+
//
63+
//
64+
// // give server ownership over the player
65+
//
66+
// serverPlayer.GetComponent<NetworkObject>().ChangeOwnership(m_ServerNetworkManager.ServerClientId);
67+
//
68+
// yield return null;
69+
// yield return null;
70+
//
71+
// // server should now be able to commit to transform
72+
// TestKinematicSetCorrectly(serverPlayer, clientPlayer);
73+
//
74+
// // return ownership to client
75+
// serverPlayer.GetComponent<NetworkObject>().ChangeOwnership(m_ClientNetworkManagers[0].LocalClientId);
76+
// yield return null;
77+
// yield return null;
78+
//
79+
// // client should again be able to commit
80+
// TestKinematicSetCorrectly(clientPlayer, serverPlayer);
81+
// }
82+
//
83+
//
84+
//
85+
// private void TestKinematicSetCorrectly(GameObject canCommitPlayer, GameObject canNotCommitPlayer)
86+
// {
87+
//
88+
// // can commit player has authority and should have a kinematic mode of false (or true in case body was already kinematic).
89+
// Assert.True(canCommitPlayer.GetComponent<Rigidbody2D>().isKinematic == Kinematic);
90+
//
91+
// // can not commit player has no authority and should have a kinematic mode of true
92+
// Assert.True(canNotCommitPlayer.GetComponent<Rigidbody2D>().isKinematic);
93+
// }
94+
// }
95+
// }

testproject/Assets/Tests/Runtime/Physics/NetworkRigidbody2DCntChangeOwnershipTest.cs.meta

Lines changed: 11 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
// using System.Collections;
2+
// using NUnit.Framework;
3+
// using Unity.Netcode.Components;
4+
// using Unity.Netcode.Samples;
5+
// using UnityEngine;
6+
// using UnityEngine.TestTools;
7+
//
8+
// // Tests for ClientNetworkTransform (CNT) + NetworkRigidbody2D. This test is in TestProject because it needs access to ClientNetworkTransform
9+
// namespace Unity.Netcode.RuntimeTests.Physics
10+
// {
11+
// public class NetworkRigidbody2DDynamicCntTest : NetworkRigidbody2DCntTestBase
12+
// {
13+
// public override bool Kinematic => false;
14+
// }
15+
//
16+
// public class NetworkRigidbody2DKinematicCntTest : NetworkRigidbody2DCntTestBase
17+
// {
18+
// public override bool Kinematic => true;
19+
// }
20+
//
21+
// public abstract class NetworkRigidbody2DCntTestBase : BaseMultiInstanceTest
22+
// {
23+
// protected override int NbClients => 1;
24+
//
25+
// public abstract bool Kinematic { get; }
26+
//
27+
// [UnitySetUp]
28+
// public override IEnumerator Setup()
29+
// {
30+
// yield return StartSomeClientsAndServerWithPlayers(true, NbClients, playerPrefab =>
31+
// {
32+
// playerPrefab.AddComponent<ClientNetworkTransform>();
33+
// playerPrefab.AddComponent<Rigidbody2D>();
34+
// playerPrefab.AddComponent<NetworkRigidbody2D>();
35+
// playerPrefab.GetComponent<Rigidbody2D>().isKinematic = Kinematic;
36+
// });
37+
// }
38+
//
39+
// /// <summary>
40+
// /// Tests that a server can destroy a NetworkObject and that it gets despawned correctly.
41+
// /// </summary>
42+
// /// <returns></returns>
43+
// [UnityTest]
44+
// public IEnumerator TestRigidbodyKinematicEnableDisable()
45+
// {
46+
// // This is the *SERVER VERSION* of the *CLIENT PLAYER*
47+
// var serverClientPlayerResult = new MultiInstanceHelpers.CoroutineResultWrapper<NetworkObject>();
48+
// yield return MultiInstanceHelpers.Run(MultiInstanceHelpers.GetNetworkObjectByRepresentation((x => x.IsPlayerObject && x.OwnerClientId == m_ClientNetworkManagers[0].LocalClientId), m_ServerNetworkManager, serverClientPlayerResult));
49+
// var serverPlayer = serverClientPlayerResult.Result.gameObject;
50+
//
51+
// // This is the *CLIENT VERSION* of the *CLIENT PLAYER*
52+
// var clientClientPlayerResult = new MultiInstanceHelpers.CoroutineResultWrapper<NetworkObject>();
53+
// yield return MultiInstanceHelpers.Run(MultiInstanceHelpers.GetNetworkObjectByRepresentation((x => x.IsPlayerObject && x.OwnerClientId == m_ClientNetworkManagers[0].LocalClientId), m_ClientNetworkManagers[0], clientClientPlayerResult));
54+
// var clientPlayer = clientClientPlayerResult.Result.gameObject;
55+
//
56+
// Assert.IsNotNull(serverPlayer);
57+
// Assert.IsNotNull(clientPlayer);
58+
//
59+
// int waitFor = Time.frameCount + 2;
60+
// yield return new WaitUntil(() => Time.frameCount >= waitFor);
61+
//
62+
// TestKinematicSetCorrectly(clientPlayer, serverPlayer);
63+
//
64+
// // despawn the server player
65+
// serverPlayer.GetComponent<NetworkObject>().Despawn(false);
66+
//
67+
// yield return null;
68+
// yield return null;
69+
// Assert.IsTrue(clientPlayer == null); // safety check that object is actually despawned.
70+
// }
71+
//
72+
// private void TestKinematicSetCorrectly(GameObject canCommitPlayer, GameObject canNotCommitPlayer)
73+
// {
74+
//
75+
// // can commit player has authority and should have a kinematic mode of false (or true in case body was already kinematic).
76+
// Assert.True(canCommitPlayer.GetComponent<Rigidbody2D>().isKinematic == Kinematic);
77+
//
78+
// // can not commit player has no authority and should have a kinematic mode of true
79+
// Assert.True(canNotCommitPlayer.GetComponent<Rigidbody2D>().isKinematic);
80+
// }
81+
// }
82+
// }

testproject/Assets/Tests/Runtime/Physics/NetworkRigidbody2DCntTest.cs.meta

Lines changed: 11 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)