Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice

Resolved ServerRPC function is called multiple times on client

Discussion in 'Netcode for GameObjects' started by DimNik97, Jun 11, 2023.

  1. DimNik97

    DimNik97

    Joined:
    Oct 19, 2022
    Posts:
    11
    Hello. I am currently learning about netcode and i am creating a simple fps multiplayer game with netcode.
    The problem that i am facing right now is that, i use a ServerRpc call for the shoot function.
    When i shoot from the host, it works perfectly, however from the clients, the shoot function is called multiple times. For example, for each mouse click, the function is called 4-5 times.


    Code (CSharp):
    1.     void Update()
    2.     {
    3.         if (!IsOwner) return;
    4.         UserInput();
    5.     }
    6.  
    7.     private void UserInput()
    8.     {
    9.  
    10.         //Input
    11.         if (allowButtonHold) shooting = Input.GetKey(KeyCode.Mouse0);
    12.         else shooting = Input.GetKeyDown(KeyCode.Mouse0);
    13.  
    14.         //Shoot
    15.         if (readyToShoot && shooting && !bulletsLeft > 0){
    16.             ShootServerRpc();
    17.         }
    18.     }
    19.  
    20.  
    21.  
    22.     [ServerRpc]
    23.     private void ShootServerRpc()
    24.     {
    25.  
    26.         Ray ray = fpsCam.ViewportPointToRay(new Vector3(0.5f, 0.5f, 0));
    27.         Vector3 targetPoint;
    28.         targetPoint = ray.GetPoint(75);
    29.    
    30.         //Calculate direction
    31.         Vector3 directionWithoutSpread = targetPoint - attackPoint.position;
    32.         //Spread
    33.         float x = Random.Range(-spread, spread);
    34.         float y = Random.Range(-spread, spread);
    35.         float z = Random.Range(-spread, spread);
    36.  
    37.         //Calc Direction with Spread
    38.         Vector3 directionWithSpread = directionWithoutSpread + new Vector3(x, y, z);
    39.  
    40.         //Instantiate bullet/projectile
    41.         GameObject currentBullet = Instantiate(bullet, attackPoint.position, Quaternion.identity);
    42.  
    43.         currentBullet.transform.forward = directionWithSpread.normalized;
    44.  
    45.         //AddForce
    46.         currentBullet.GetComponent<Rigidbody>().AddForce(directionWithSpread.normalized * shootForce, ForceMode.Impulse);
    47.  
    48.         bulletsLeft--;
    49.         bulletsShot--;
    50.  
    51.         if (allowInvoke)
    52.         {
    53.             Invoke("ShotReset", timeBetweenShooting);
    54.             allowInvoke = false;
    55.         }
    56.  
    57.         currentBullet.GetComponent<NetworkObject>().Spawn();
    58.  
    59.     }
    60.  
     
  2. Mj-Kkaya

    Mj-Kkaya

    Joined:
    Oct 10, 2017
    Posts:
    179
    Where do you change "readyToShoot" and "bulletsLeft" variable on client side?
    Because "ShootServerRpc" is just run on Host side not client side.
     
  3. DimNik97

    DimNik97

    Joined:
    Oct 19, 2022
    Posts:
    11
    Thanks for your reply. I am not changing these 2 variables somewhere else tbh.
    So, if im right, you mean that these 2 variables are always the same for the client, because they only change inside the ServerRpc function? So i have to modify them somewhere else, which will only be for the client?
     
  4. RikuTheFuffs-U

    RikuTheFuffs-U

    Unity Technologies

    Joined:
    Feb 20, 2020
    Posts:
    440
    You have to tell the client they changed, for sure. The server should know about these to, because ultimately the server is the one who should decide whether the client can shoot or not (to avoid cheating).

    You can have a NetworkVariable to represent this data, or you could move the checks entirely to the server
     
    mcdoggus14 likes this.
  5. Mj-Kkaya

    Mj-Kkaya

    Joined:
    Oct 10, 2017
    Posts:
    179
    Yes this is exactly what I said.
    So, Client runs "ShootServerRpc()" method but doesn't change any variable.
    Because of this "if (readyToShoot && shooting && !bulletsLeft > 0)" condition will always be same and never change.

    I can't see your all code but, I guess you miss that point.
     
  6. DimNik97

    DimNik97

    Joined:
    Oct 19, 2022
    Posts:
    11
    Thank you everyone for your answers, i figured it out.
    The concept around Server & Client Rpc's was a bit confusing to me, but i now start to understand it better.
     
    Mj-Kkaya likes this.