I have a physics based bullet which is handled on the server. When a player is hit I want to send a message to the player which has been hit. I’m using the code below. When the PlayerHitClientRpc is run it only reaches the server (client id 0). Is there something wrong with my code/logic or could the problem lie somewhere else?
Hi @NorthernLight , to send the RPC to a specific client you should use the ClientRpcSendParams parameter, see the example here. Moreover, I’d recommend that you make your health server-authoritative through a syncvar, otherwise clients will be able to cheat the TakeDamage() method.
Hi, and thank you for the tip regarding moving my health management. I will implement that later. For now I just want to make sure the hit is communicated to the player. I changed my code so that the clientRpc method targets a specific client but it’s not working. My updated code:
void FixedUpdate()
{
if (collisionCheck)
{
if (IsServer)
{
RaycastHit hit;
if (Physics.Linecast(lastpos, tf.position, out hit, layersToHit))
{
if (hit.transform.GetComponent<NetworkObject>())
{
ClientRpcParams clientRpcParams = new ClientRpcParams
{
Send = new ClientRpcSendParams
{
TargetClientIds = new ulong[] { hit.transform.GetComponent<NetworkObject>().OwnerClientId }
}
};
PlayerHitClientRpc( damagePotential, clientRpcParams);
}
GameObject go = Instantiate(explosionPrefab, hit.point, Quaternion.LookRotation(hit.normal));
go.GetComponent<NetworkObject>().Spawn();
gameObject.GetComponent<NetworkObject>().Despawn();
}
else
{
lastpos = tf.position;
}
}
}
}
[ClientRpc]
private void PlayerHitClientRpc(float dmg, ClientRpcParams clientID)
{
GetComponent<PlayerHealth>().TakeDamage(dmg);
}
Sorry for the vagueness. Not working as in no clients are reached. Even when sent directly to the client the method TakeDamage is not executed. The client doesn’t receive the clientRpc call. Same problem as when I sent the clientRpc call to all clients. I used Netcode 1.1.0 but today I updated to 1.2.0. No changes.
I’m using Client Network Transform on the player objects. Could that be a problem?
Nope, but I re-read your original post and noticed that you said the host receives the RPC. Are you sure the clients are actually owners of their players? Otherwise OwnerClientId will always return the host.
I think so. I have implemented some checks of their OwnerClientId before registering the hit and sending the clientRpc call. It shows the right id number when the bullet hits. My updated code is below. (Did some changes to the code and the objects). The “receiving damage” message refuses to appear, but the “was hit” message shows the right OwnerClientId.
…or am I misunderstanding something when you say “actually owners of their players”?
void FixedUpdate()
{
if (collisionCheck)
{
if (!IsServer)
{
return;
}
RaycastHit hit;
if (Physics.Linecast(lastpos, tf.position, out hit, layersToHit))
{
if (hit.transform.GetComponentInParent<NetworkObject>())
{
print("Client: " + hit.transform.GetComponentInParent<NetworkObject>().OwnerClientId.ToString() + " was hit");
ClientRpcParams clientRpcParams = new ClientRpcParams
{
Send = new ClientRpcSendParams
{
TargetClientIds = new ulong[] { hit.transform.GetComponentInParent<NetworkObject>().OwnerClientId }
}
};
PlayerHitClientRpc( damagePotential, clientRpcParams);
}
GameObject go = Instantiate(explosionPrefab, hit.point, Quaternion.LookRotation(hit.normal));
go.GetComponent<NetworkObject>().Spawn();
gameObject.GetComponent<NetworkObject>().Despawn();
}
else
{
lastpos = tf.position;
}
}
}
[ClientRpc]
private void PlayerHitClientRpc(float dmg, ClientRpcParams clientID)
{
print(clientID + " receiving damage");
GetComponent<PlayerHealth>().TakeDamage(dmg);
}