I am testing my game in host mode as the lone client.
I call a server RPC to spawn an object. I have verified that this function is only called once.
Inside the server RPC I call a client RPC to inject dependencies for the player.
I want to send this call only to the client whose player is in control of the object, so I use ClientRpcParams.
Inside the client RPC function I get the Id of this client with clientRpcParams.Send.TargetClientIds[0]
There are 2 behaviors I don’t understand.
The TargetClientIds object is null and a NRE is raised.
The function is called again and TargetClientIds is no longer null.
Can someone please explain? Does the NRE cause the RPC to trigger a 2nd time? Is it related to RpcDeliveryMode.Reliable? Why is the value null the first time? Why isn’t it null the 2nd time?
Here is my code
[ServerRpc]
internal void SpawnPieceServerRpc(NetworkGuid guid, Vector3 position, ulong ownerId, VisibilityMode visibility)
{
Debug.Log("Spawning");
if (m_PieceRegistry.TryGetPiece(guid.ToGuid(), out var pieceData))
{
var prefab = pieceData.isStatic ? m_StaticPiecePrefab : m_MovablePiecePrefab;
PieceDataWrapper newPiece = Instantiate(prefab);
newPiece.name = pieceData.GetType().Name;
newPiece.Data = pieceData;
newPiece.transform.position = position;
if (visibility == VisibilityMode.LocalPlayerOnly)
newPiece.NetworkObject.CheckObjectVisibility += (clientId) => clientId == ownerId;
newPiece.NetworkObject.Spawn();
newPiece.NetworkObject.ChangeOwnership(ownerId);
if (!pieceData.isStatic)
{
m_ClientCallbacks.InjectPieceDependencyClientRpc(newPiece.NetworkObjectId, new ClientRpcParams
{
Send = new ClientRpcSendParams
{
TargetClientIds = new ulong[] { ownerId },
}
});
}
m_ClientCallbacks.SpawnAvatarClientRpc(newPiece.NetworkObject.NetworkObjectId, guid);
}
else
{
Debug.LogError("Unable to match GUID for piece");
}
}
There’s Send and Receive parts of ClientRpcParams, the Send part is only set on the server and it would be the Receive part you check on the client, although it’s currently not used. You shouldn’t need any additional checks inside the ClientRpc as if it was called it was meant for that client.
It does look like the rpc being called twice is a side effect of the exception on the host as it’s only called once otherwise.
In theory yes. I haven’t tested to see that it is not being called on other clients. But it shouldn’t cause any issues either I would think. I’m just trying to understand this unexpected behavior.
I just got rid of my if statement checking the clientId and trusted the clientrpsparams to do its job. It worked fine. Never figured out my I was getting null.
I’ve since moved on to Fishnet which is a much more feature complete solution, and they have a discord which is sometimes helpful. Although there are some aspects of NGO I miss, the addition of client side prediction, rollback, lag compensation, network lod, etc. all built in make it a no brainer. It’s also much more scalable than NGO out of the box.