Unity-Technologies / com.unity.netcode.gameobjects

Netcode for GameObjects is a high-level netcode SDK that provides networking capabilities to GameObject/MonoBehaviour workflows within Unity and sits on top of underlying transport layer.
MIT License
2.1k stars 430 forks source link

Host executes "Rpc NotMe" twice with each call (1.8.0) #2827

Closed ervacoban closed 4 months ago

ervacoban commented 4 months ago

Description

When a client, that is not the host, executes an Rpc with target set to NotMe, the host will execute the Rpc twice, locally.

Reproduce Steps

  1. Create an empty scene with a network manager and transport.
  2. Create a script that inherits from NetworkBehaviour and add it to an empty object in the scene.
  3. Add an rpc function with the target set to [Rpc(SendTo.NotMe)] and add Debug.Log("Not Me RPC Executed"); to the function.
  4. Run a host and a client version. (I am using ParrelSync to connect as a client)
  5. Execute the function from a client
  6. Host will debug the message to the console twice with each call.

Actual Outcome

When I was executing rpcs with clients, the host executed the rpcs twice, while clients only executed it once. The host should only execute it once as well. This only happens on the host, when a regular client executes the rpc. So this problem does not occur on regular clients.

Expected Outcome

The rpc should only execute once with each call, just like clients.

Screenshots

Host console when rpc was executed from a client: (Bug) Host

Client console when rpc was executed from the host: (Correct) Client

Environment

Additional Context

The same problem occured when I was using Unity version 2022.3.10f1 and Netcode 1.8.0 (manual upgrade)

miniwolf commented 4 months ago

What is happening is that when sending the RPC - NotMeRpcTarget.cs code in question:

m_GroupSendTarget.Target.Send(behaviour, ref message, delivery, rpcParams);
if (!behaviour.IsServer)
{
    m_ServerRpcTarget.Send(behaviour, ref message, delivery, rpcParams);
}

It will gather the client side of the host and send the RPC but then also send it to the server (which is also the host). Because the host acts as both client and server it will receive two messages.

This could be solved by changing the code to:

m_GroupSendTarget.Target.Send(behaviour, ref message, delivery, rpcParams);
if (!behaviour.IsServer && !m_NetworkManager.ServerIsHost)
{
    m_ServerRpcTarget.Send(behaviour, ref message, delivery, rpcParams);
}
miniwolf commented 4 months ago

Fix is in this PR: https://github.com/Unity-Technologies/com.unity.netcode.gameobjects/pull/2834 Will land in an upcoming release