Skip to content

Commit de3fc7c

Browse files
ShadauxCatjakobbbb
authored andcommitted
fix: Client RPCs always reporting all RPCs as going to all clients, even when limited by ClientRpcParams [MTT-4468] (Unity-Technologies#2144)
* fix: Client RPCs always reporting all RPCs as going to all clients, even when limited by ClientRpcParams * Changelog
1 parent 1b1d8c0 commit de3fc7c

4 files changed

Lines changed: 98 additions & 19 deletions

File tree

com.unity.netcode.gameobjects/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ Additional documentation and release notes are available at [Multiplayer Documen
1111

1212
### Fixed
1313

14+
- Fixed ClientRpcs always reporting in the profiler view as going to all clients, even when limited to a subset of clients by ClientRpcParams. (#2144)
1415
- Fixed RPC codegen failing to choose the correct extension methods for FastBufferReader and FastBufferWriter when the parameters were a generic type (i.e., List<int>) and extensions for multiple instantiations of that type have been defined (i.e., List<int> and List<string>) (#2142)
1516
- Fixed throwing an exception in OnNetworkUpdate causing other OnNetworkUpdate calls to not be executed. (#1739)
1617

com.unity.netcode.gameobjects/Runtime/Core/NetworkBehaviour.cs

Lines changed: 35 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -235,14 +235,42 @@ internal void __endSendClientRpc(ref FastBufferWriter bufferWriter, uint rpcMeth
235235
#if DEVELOPMENT_BUILD || UNITY_EDITOR
236236
if (NetworkManager.__rpc_name_table.TryGetValue(rpcMethodId, out var rpcMethodName))
237237
{
238-
foreach (var client in NetworkManager.ConnectedClients)
238+
if (clientRpcParams.Send.TargetClientIds != null)
239239
{
240-
NetworkManager.NetworkMetrics.TrackRpcSent(
241-
client.Key,
242-
NetworkObject,
243-
rpcMethodName,
244-
__getTypeName(),
245-
rpcWriteSize);
240+
foreach (var targetClientId in clientRpcParams.Send.TargetClientIds)
241+
{
242+
NetworkManager.NetworkMetrics.TrackRpcSent(
243+
targetClientId,
244+
NetworkObject,
245+
rpcMethodName,
246+
__getTypeName(),
247+
rpcWriteSize);
248+
}
249+
}
250+
else if (clientRpcParams.Send.TargetClientIdsNativeArray != null)
251+
{
252+
foreach (var targetClientId in clientRpcParams.Send.TargetClientIdsNativeArray)
253+
{
254+
NetworkManager.NetworkMetrics.TrackRpcSent(
255+
targetClientId,
256+
NetworkObject,
257+
rpcMethodName,
258+
__getTypeName(),
259+
rpcWriteSize);
260+
}
261+
}
262+
else
263+
{
264+
var observerEnumerator = NetworkObject.Observers.GetEnumerator();
265+
while (observerEnumerator.MoveNext())
266+
{
267+
NetworkManager.NetworkMetrics.TrackRpcSent(
268+
observerEnumerator.Current,
269+
NetworkObject,
270+
rpcMethodName,
271+
__getTypeName(),
272+
rpcWriteSize);
273+
}
246274
}
247275
}
248276
#endif

com.unity.netcode.gameobjects/TestHelpers/Runtime/Metrics/RpcTestComponent.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ public void MyServerRpc()
1414
}
1515

1616
[ClientRpc]
17-
public void MyClientRpc()
17+
public void MyClientRpc(ClientRpcParams rpcParams = default)
1818
{
1919
OnClientRpcAction?.Invoke();
2020
}

com.unity.netcode.gameobjects/Tests/Runtime/Metrics/RpcMetricsTests.cs

Lines changed: 61 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,14 @@
22
using System.Collections;
33
using System.Linq;
44
using NUnit.Framework;
5+
using Unity.Collections;
56
using Unity.Multiplayer.Tools.MetricTypes;
67
using UnityEngine.TestTools;
78
using Unity.Netcode.TestHelpers.Runtime.Metrics;
89

910
namespace Unity.Netcode.RuntimeTests.Metrics
1011
{
11-
internal class RpcMetricsTests : SingleClientMetricTestBase
12+
internal class RpcMetricsTests : DualClientMetricTestBase
1213
{
1314
protected override void OnCreatePlayerPrefab()
1415
{
@@ -17,30 +18,79 @@ protected override void OnCreatePlayerPrefab()
1718
}
1819

1920
[UnityTest]
20-
public IEnumerator TrackRpcSentMetricOnServer()
21+
public IEnumerator TrackRpcSentMetricOnServerToOnlyOneClientWithArray()
2122
{
2223
var waitForMetricValues = new WaitForEventMetricValues<RpcEvent>(ServerMetrics.Dispatcher, NetworkMetricTypes.RpcSent);
2324

24-
m_PlayerNetworkObjects[m_ServerNetworkManager.LocalClientId][Client.LocalClientId].GetComponent<RpcTestComponent>().MyClientRpc();
25+
m_PlayerNetworkObjects[m_ServerNetworkManager.LocalClientId][FirstClient.LocalClientId].GetComponent<RpcTestComponent>().MyClientRpc(new ClientRpcParams
26+
{
27+
Send = new ClientRpcSendParams
28+
{
29+
TargetClientIds = new []{FirstClient.LocalClientId}
30+
}
31+
});
2532

2633
yield return waitForMetricValues.WaitForMetricsReceived();
2734

2835
var serverRpcSentValues = waitForMetricValues.AssertMetricValuesHaveBeenFound();
29-
Assert.AreEqual(2, serverRpcSentValues.Count); // Server will receive this, since it's host
36+
Assert.AreEqual(1, serverRpcSentValues.Count);
37+
38+
Assert.That(serverRpcSentValues, Has.All.Matches<RpcEvent>(x => x.Name == nameof(RpcTestComponent.MyClientRpc)));
39+
Assert.That(serverRpcSentValues, Has.All.Matches<RpcEvent>(x => x.NetworkBehaviourName == nameof(RpcTestComponent)));
40+
Assert.That(serverRpcSentValues, Has.All.Matches<RpcEvent>(x => x.BytesCount != 0));
41+
Assert.AreEqual(FirstClient.LocalClientId, serverRpcSentValues.First().Connection.Id);
42+
}
43+
44+
[UnityTest]
45+
public IEnumerator TrackRpcSentMetricOnServerToOnlyOneClientWithNativeArray()
46+
{
47+
var waitForMetricValues = new WaitForEventMetricValues<RpcEvent>(ServerMetrics.Dispatcher, NetworkMetricTypes.RpcSent);
48+
49+
m_PlayerNetworkObjects[m_ServerNetworkManager.LocalClientId][FirstClient.LocalClientId].GetComponent<RpcTestComponent>().MyClientRpc(new ClientRpcParams
50+
{
51+
Send = new ClientRpcSendParams
52+
{
53+
TargetClientIdsNativeArray = new NativeArray<ulong>(new []{FirstClient.LocalClientId}, Allocator.Temp)
54+
}
55+
});
56+
57+
yield return waitForMetricValues.WaitForMetricsReceived();
58+
59+
var serverRpcSentValues = waitForMetricValues.AssertMetricValuesHaveBeenFound();
60+
Assert.AreEqual(1, serverRpcSentValues.Count);
61+
62+
Assert.That(serverRpcSentValues, Has.All.Matches<RpcEvent>(x => x.Name == nameof(RpcTestComponent.MyClientRpc)));
63+
Assert.That(serverRpcSentValues, Has.All.Matches<RpcEvent>(x => x.NetworkBehaviourName == nameof(RpcTestComponent)));
64+
Assert.That(serverRpcSentValues, Has.All.Matches<RpcEvent>(x => x.BytesCount != 0));
65+
Assert.AreEqual(FirstClient.LocalClientId, serverRpcSentValues.First().Connection.Id);
66+
}
67+
68+
[UnityTest]
69+
public IEnumerator TrackRpcSentMetricOnServerToAllClients()
70+
{
71+
var waitForMetricValues = new WaitForEventMetricValues<RpcEvent>(ServerMetrics.Dispatcher, NetworkMetricTypes.RpcSent);
72+
73+
m_PlayerNetworkObjects[m_ServerNetworkManager.LocalClientId][FirstClient.LocalClientId].GetComponent<RpcTestComponent>().MyClientRpc();
74+
75+
yield return waitForMetricValues.WaitForMetricsReceived();
76+
77+
var serverRpcSentValues = waitForMetricValues.AssertMetricValuesHaveBeenFound();
78+
Assert.AreEqual(3, serverRpcSentValues.Count); // Server will receive this, since it's host
3079

3180
Assert.That(serverRpcSentValues, Has.All.Matches<RpcEvent>(x => x.Name == nameof(RpcTestComponent.MyClientRpc)));
3281
Assert.That(serverRpcSentValues, Has.All.Matches<RpcEvent>(x => x.NetworkBehaviourName == nameof(RpcTestComponent)));
3382
Assert.That(serverRpcSentValues, Has.All.Matches<RpcEvent>(x => x.BytesCount != 0));
3483
Assert.Contains(Server.LocalClientId, serverRpcSentValues.Select(x => x.Connection.Id).ToArray());
35-
Assert.Contains(Client.LocalClientId, serverRpcSentValues.Select(x => x.Connection.Id).ToArray());
84+
Assert.Contains(FirstClient.LocalClientId, serverRpcSentValues.Select(x => x.Connection.Id).ToArray());
85+
Assert.Contains(SecondClient.LocalClientId, serverRpcSentValues.Select(x => x.Connection.Id).ToArray());
3686
}
3787

3888
[UnityTest]
3989
public IEnumerator TrackRpcSentMetricOnClient()
4090
{
41-
var waitForClientMetricsValues = new WaitForEventMetricValues<RpcEvent>(ClientMetrics.Dispatcher, NetworkMetricTypes.RpcSent);
91+
var waitForClientMetricsValues = new WaitForEventMetricValues<RpcEvent>(FirstClientMetrics.Dispatcher, NetworkMetricTypes.RpcSent);
4292

43-
m_PlayerNetworkObjects[Client.LocalClientId][Client.LocalClientId].GetComponent<RpcTestComponent>().MyServerRpc();
93+
m_PlayerNetworkObjects[FirstClient.LocalClientId][FirstClient.LocalClientId].GetComponent<RpcTestComponent>().MyServerRpc();
4494

4595
yield return waitForClientMetricsValues.WaitForMetricsReceived();
4696

@@ -58,15 +108,15 @@ public IEnumerator TrackRpcSentMetricOnClient()
58108
public IEnumerator TrackRpcReceivedMetricOnServer()
59109
{
60110
var waitForServerMetricsValues = new WaitForEventMetricValues<RpcEvent>(ServerMetrics.Dispatcher, NetworkMetricTypes.RpcReceived);
61-
m_PlayerNetworkObjects[Client.LocalClientId][Client.LocalClientId].GetComponent<RpcTestComponent>().MyServerRpc();
111+
m_PlayerNetworkObjects[FirstClient.LocalClientId][FirstClient.LocalClientId].GetComponent<RpcTestComponent>().MyServerRpc();
62112

63113
yield return waitForServerMetricsValues.WaitForMetricsReceived();
64114

65115
var serverRpcReceivedValues = waitForServerMetricsValues.AssertMetricValuesHaveBeenFound();
66116
Assert.AreEqual(1, serverRpcReceivedValues.Count);
67117

68118
var rpcReceived = serverRpcReceivedValues.First();
69-
Assert.AreEqual(Client.LocalClientId, rpcReceived.Connection.Id);
119+
Assert.AreEqual(FirstClient.LocalClientId, rpcReceived.Connection.Id);
70120
Assert.AreEqual(nameof(RpcTestComponent.MyServerRpc), rpcReceived.Name);
71121
Assert.AreEqual(nameof(RpcTestComponent), rpcReceived.NetworkBehaviourName);
72122
Assert.AreNotEqual(0, rpcReceived.BytesCount);
@@ -75,9 +125,9 @@ public IEnumerator TrackRpcReceivedMetricOnServer()
75125
[UnityTest]
76126
public IEnumerator TrackRpcReceivedMetricOnClient()
77127
{
78-
var waitForClientMetricsValues = new WaitForEventMetricValues<RpcEvent>(ClientMetrics.Dispatcher, NetworkMetricTypes.RpcReceived);
128+
var waitForClientMetricsValues = new WaitForEventMetricValues<RpcEvent>(FirstClientMetrics.Dispatcher, NetworkMetricTypes.RpcReceived);
79129

80-
m_PlayerNetworkObjects[m_ServerNetworkManager.LocalClientId][Client.LocalClientId].GetComponent<RpcTestComponent>().MyClientRpc();
130+
m_PlayerNetworkObjects[m_ServerNetworkManager.LocalClientId][FirstClient.LocalClientId].GetComponent<RpcTestComponent>().MyClientRpc();
81131

82132
yield return waitForClientMetricsValues.WaitForMetricsReceived();
83133

0 commit comments

Comments
 (0)