error while trying to send a ClientRpc to a specific client in Unity Netcode

457 Views Asked by At

i am building an online multiplayer game where players(clients) are rolling marbles that navigate through a map.Each player is spawned form the same prefab using the network manager and have the same script as well as network object and client network transform components.I want to implement when the players collide with each other, to apply a bouncing back force to the other player. I am having a weird issue when calling the client Rpc using the clientParams where the debug message is printed to the correct client log but when i check the OwnerClientId it seems to be on the wrong client

public class PlayerNetwork : NetworkBehaviour
{
    [SerializeField] public float speed;
    [SerializeField] public Transform cameraPrefab;

    private Rigidbody rb;
    private Transform camera;
    public CinemachineFreeLook freelookcamera;
    public NetworkVariable<int> lives = new(3, NetworkVariableReadPermission.Everyone,      NetworkVariableWritePermission.Owner);
    private int move = 0;

    public Transform target;

    public static event System.Action<int> ChangedLivesEvent;




    void Start()
    {

        if (IsOwner)
        {
          Debug.Log("my id is: " + OwnerClientId);
          Cursor.visible = false;
          rb = GetComponent<Rigidbody>();
          freelookcamera.Priority = 10;
          freelookcamera.Follow = target.transform;
          freelookcamera.LookAt = target.transform;

          camera = Instantiate(cameraPrefab);


        }

        if(IsOwner == false) {
           freelookcamera.Priority = 0;
        }
    }





    private void OnCollisionEnter(Collision collision)
    {
        Debug.Log("collision 1");


        Debug.Log(collision.gameObject.tag);
        if (!collision.gameObject.CompareTag("Player")) return;

        if(!IsOwner) return;

        Debug.Log("collision 2");


        if (collision.gameObject.TryGetComponent(out PlayerNetwork playerNetwork))
        {
            Debug.Log("collision 4" + OwnerClientId + transform.position);
            Debug.Log("collision 4" + playerNetwork.OwnerClientId +                        playerNetwork.transform.position); 

            var player1 = new PlayerData() {
              Id = OwnerClientId,
              Direction = -(playerNetwork.transform.position - transform.position).normalized
            };

            var player2 = new PlayerData() {
              Id = playerNetwork.OwnerClientId,
              Direction = (playerNetwork.transform.position - transform.position).normalized
            };

          
            ApplyForceServerRpc(player1, player2);
        }
    }





      struct PlayerData : INetworkSerializable {
        public ulong Id;
        public Vector3 Direction;

        public void NetworkSerialize<T>(BufferSerializer<T> serializer) where T : IReaderWriter {
          serializer.SerializeValue(ref Id);
          serializer.SerializeValue(ref Direction);
      }
    }





    [ServerRpc]
    private void ApplyForceServerRpc(PlayerData player1, PlayerData player2)
    {

        Debug.Log("Server player1 id  "+ player1.Id);
        Debug.Log("Server player2 id  "+ player2.Id);

        if (NetworkManager.Singleton.ConnectedClients[player2.Id].ClientId == NetworkManager.ServerClientId)
        {
 
            var player2Object = NetworkManager.Singleton.ConnectedClients[player2.Id].PlayerObject;
            var player2Rigidbody = player2Object.GetComponentInChildren<Rigidbody>();
            player2Rigidbody.AddForce(player2.Direction * 500f);
        }
        else
        {
            // Player 2 is a client, invoke a client RPC to apply the force
            ApplyForce2ServerRpc(player2.Direction, player2.Id);
        }




    [ServerRpc]
    private void ApplyForce2ServerRpc(Vector3 force, ulong identity) {
      
      ApplyForceClientRpc(force, new ClientRpcParams
      {
          Send = new ClientRpcSendParams
          {
              TargetClientIds = new ulong[] { identity }
          }
      });
    }




    [ClientRpc]
    private void ApplyForceClientRpc(Vector3 force2, ClientRpcParams clientRpcParams = default)
    {
        Debug.Log("Client log" + OwnerClientId);
        if(!IsOwner) return;
        Debug.Log("Client log 2" + OwnerClientId);
        rb.AddForce(force2*500f);

    }




    void FixedUpdate()
    {
        if (!IsOwner) return;

        if (move==0) {
          float moveHorizontal = Input.GetAxis("Horizontal");
          float moveVertical = Input.GetAxis("Vertical");

          Vector3 movement = new Vector3(moveHorizontal, 0.0f, moveVertical);
          movement = Quaternion.AngleAxis(camera.rotation.eulerAngles.y, Vector3.up) * movement;

          rb.AddForce(movement * speed);
        }
        else{
          Debug.Log("stopped");
          return;
        }

    }
}

Two players with id 0 and 1 collide. the collision is detected on the first player with id 0. So in the server Rpc player1.id = 0 and player2.id = 1. The player2.id is passed in the next server Rpc and then to the client Rpc using the RpcParams in order to find the client corresponding to the player2.Id. So logically the client with id = 1 should execute the code written in the clientRpc. The Debug.Log("Client log" + OwnerClientId); is correctly outputted in the log file of the client with Id 1 but the code for some reason is run on the client with Id 0. Hence the log file prints the following when printing the OwnerClientId: Client Log 0

0

There are 0 best solutions below