Search Unity

Question Calling Rigidbody.velocity in Server

Discussion in 'Netcode for GameObjects' started by Kadir-, Jul 24, 2021.

  1. Kadir-

    Kadir-

    Joined:
    Mar 24, 2020
    Posts:
    14
    How to call Rigidbody.velocity in server so that all clients can see it.
     
  2. luke-unity

    luke-unity

    Joined:
    Sep 30, 2020
    Posts:
    306
    Can you provide some more details on what you are trying to do?
     
    Kadir- likes this.
  3. Kadir-

    Kadir-

    Joined:
    Mar 24, 2020
    Posts:
    14
    Code (CSharp):
    1.  
    2. void Update()
    3.     {
    4.         if (!IsOwner)
    5.         {
    6.             return;
    7.         }
    8.  
    9.         if (Input.GetButtonDown("Fire1"))
    10.         {
    11.             FireServerRpc();
    12.         }
    13.         if (Input.GetButtonUp("Fire1"))
    14.        {
    15.             StopFireServerRpc();
    16.        }
    17.     }
    18.  
    19.     [ServerRpc]
    20.     private void StopFireServerRpc()
    21.     {
    22.         StopCoroutine(firingCorutine);  // IEnumerator firingCorutine = FireContinuously()
    23.     }
    24.  
    25.  
    26.     [ServerRpc]
    27.     private void FireServerRpc()
    28.     {
    29.             StartCoroutine(firingCorutine);
    30.     }
    31.  
    32.     IEnumerator FireContinuously()
    33.     {
    34.         while (true)
    35.         {
    36.              NetworkObject laser = Instantiate(laserPrefab, transform.position, Quaternion.identity);      
    37.  
    38.             laser.SpawnWithOwnership(OwnerClientId); // Spawn works fine.
    39.  
    40.             laser.GetComponent<Rigidbody2D>().velocity = new Vector2(0, projectileSpeed); //This line is the problem.
    41.             // This above line works for only host, if host fires every clients can see the host's laser moving,
    42. //but if a client fires no other clients nor the host can see the laser moving.
    43. // I want to achieve this using rigidbody so as to detect collision and trigger
    44.      
    45.  
    46.             yield return new WaitForSeconds(projectileFiringPeriod);
    47.         }
    48.     }
    49.  
    50.  
     
    Last edited: Jul 27, 2021
  4. luke-unity

    luke-unity

    Joined:
    Sep 30, 2020
    Posts:
    306
    So to make this work you would need to either use a a ClientRPC or a NetworkVariable to set the velocity of your lasers on all clients. I think the easiest way here would be to add a NetworkBehaviour with a velocity NetworkVariable to your laser. Then set that value before you spawn the laser and in `NetworkStart` set the rigidbody's velocity to the value of the NetworkVariable.
     
  5. Kadir-

    Kadir-

    Joined:
    Mar 24, 2020
    Posts:
    14
    Tried but doesn't work
    Code (CSharp):
    1.    
    2.  
    3. private NetworkVariable<float> laserSpeed = new NetworkVariable<float>(20f);
    4.  NetworkObject laser; //cache
    5.  
    6.  
    7.  
    8. public override void NetworkStart()
    9.     {
    10.         laserSpeed.Value = projectileSpeed;
    11.     }
    12.  
    13.     void Update()
    14.         {
    15.             if (!IsOwner)
    16.             {
    17.                 return;
    18.             }
    19.  
    20.             if (Input.GetButtonDown("Fire1"))
    21.             {
    22.                 FireServerRpc();
    23.             }
    24.             if (Input.GetButtonUp("Fire1"))
    25.            {
    26.                 StopFireServerRpc();
    27.            }
    28.         }
    29.  
    30.         [ServerRpc]
    31.         private void StopFireServerRpc()
    32.         {
    33.             StopCoroutine(firingCorutine);  // IEnumerator firingCorutine = FireContinuously()
    34.         }
    35.  
    36.  
    37.         [ServerRpc]
    38.         private void FireServerRpc()
    39.         {
    40.                 StartCoroutine(firingCorutine);
    41.         }
    42.  
    43.         IEnumerator FireContinuously()
    44.         {
    45.             while (true)
    46.             {
    47.                 laser = Instantiate(laserPrefab, transform.position, Quaternion.identity);  // 'laser' declared above
    48.  
    49.                 laser.SpawnWithOwnership(OwnerClientId); // Spawn works fine.  
    50.            
    51.                 laser.GetComponent<Rigidbody2D>().velocity = new Vector2(0, laserSpeed.Value); // doesn't work
    52.              
    53.                 // Aslo tried with ClientRpc but doesn't work
    54.               // LaserMoveClientRpc();
    55.  
    56.              
    57.      
    58.  
    59.                 yield return new WaitForSeconds(projectileFiringPeriod);
    60.             }
    61.         }
    62.    
    63.  /*[ClientRpc]
    64.     private void LaserMoveClientRpc()
    65.     {
    66.  
    67.         laser.GetComponent<Rigidbody2D>().velocity = new Vector2(0, laserSpeed.Value); //laser decalred above
    68.        // this above line shows "object reference not set as an intense of an object" when client fire laser
    69.  
    70.     }*/
    71.  
    72.  
    Will be great if correct code is given for accessing rigidbody.velocity for this case
     
  6. luke-unity

    luke-unity

    Joined:
    Sep 30, 2020
    Posts:
    306
    I think this network behaviour is your weapon and not the laser. You want to add a separate Laser network behaviour onto your laser object. Something like:

    Code (CSharp):
    1. public class Laser : NetworkBehaviour
    2. {
    3.     public NetworkVariable<float> LaserVelocity = new NetworkVariable<float>(20f);
    4.  
    5.     public override void NetworkStart()
    6.     {
    7.         GetComponent<Rigidbody2D>().velocity = new Vector2(0, LaserVelocity.Value);
    8.     }
    9.  
    10. }
    11.  
    Then put this onto your laser and when you spawn it do:
    Code (CSharp):
    1.   IEnumerator FireContinuously()
    2.         {
    3.             while (true)
    4.             {
    5.                 laser = Instantiate(laserPrefab, transform.position, Quaternion.identity);  // 'laser' declared above
    6.  
    7.                 laser.GetComponent<Laser>().LaserVelocity.Value = projectileSpeed;
    8.  
    9.                 laser.SpawnWithOwnership(OwnerClientId); // Spawn works fine.
    10.    
    11.                 yield return new WaitForSeconds(projectileFiringPeriod);
    12.             }
    13.         }
     
  7. Kadir-

    Kadir-

    Joined:
    Mar 24, 2020
    Posts:
    14
    It works, thanks for the guidance and the knowledge. :)
     
    Last edited: Jul 28, 2021