Search Unity

[Command] -related problem: Objects don't instantiate on other clients.

Discussion in 'Multiplayer' started by Raatopojat, Dec 11, 2015.

  1. Raatopojat

    Raatopojat

    Joined:
    May 9, 2014
    Posts:
    10
    Hello.

    We are making a ship battle game that's played over the internet. The first player creates a server that other players can join into. Right now the ships spawn correctly and they move on all clients, but cannon shots only show on the player's own client. The cannon shots are instantiated objects that have velocity set in relation to the ship it's fired from. The cannonballs have their own Network Identity with Local Player Authority unchecked. They also have Network Transform with Sync Rigidbody 3D. Cannonball prefab is also registered as spawnable prefab.

    Can you help us understand what's wrong with our code? Is [Command] a good way to make this happen?

    The following code is linked to the player that instantiates the object:

    Code (CSharp):
    1.  
    2.     void FixedUpdate () {
    3.  
    4.         if (!_identity.isLocalPlayer)
    5.             return;
    6.  
    7.         if (Input.GetKey(KeyCode.Q) && Time.time > _nextFire)
    8.         {
    9.             _nextFire = Time.time + _fireRate;
    10.             CmdDoFireV(_missileLifetime);
    11.         }
    12.  
    13.         if (Input.GetKey(KeyCode.E) && Time.time > _nextFire2)
    14.         {
    15.             _nextFire2 = Time.time + _fireRate2;
    16.             CmdDoFireO(_missileLifetime);
    17.        
    18.         }
    19.  
    20.  
    21.     }
    22.  
    23.  
    24.  
    25.     private GameObject missile;
    26.     private GameObject missile1;
    27.     private GameObject missile2;
    28.     private GameObject missile3;
    29.     private GameObject missile4;
    30.     private GameObject missile5;
    31.     private GameObject missile6;
    32.     private GameObject missile7;
    33.  
    34.    [Command]
    35.     void CmdDoFireV(float lifeTime)
    36.     {
    37.  
    38.         missile = (GameObject)Instantiate(_missilePrefab, _missileSpawnPoint.position, Quaternion.identity);
    39.    
    40.         missile1 = (GameObject)Instantiate(_missilePrefab, _missileSpawnPoint1.position, Quaternion.identity);
    41.  
    42.         missile2 = (GameObject)Instantiate(_missilePrefab, _missileSpawnPoint2.position, Quaternion.identity);
    43.    
    44.         missile3 = (GameObject)Instantiate(_missilePrefab, _missileSpawnPoint3.position, Quaternion.identity);
    45.  
    46.         Rigidbody rigid = missile.GetComponent<Rigidbody>();
    47.         rigid.velocity = ship.GetComponent<Rigidbody>().velocity + (transform.right * -_missileSpeed);
    48.         Destroy(missile, lifeTime);
    49.  
    50.         Rigidbody rigid1 = missile1.GetComponent<Rigidbody>();
    51.         rigid1.velocity = ship.GetComponent<Rigidbody>().velocity + (transform.right * -_missileSpeed);
    52.         Destroy(missile1, lifeTime);
    53.  
    54.         Rigidbody rigid2 = missile2.GetComponent<Rigidbody>();
    55.         rigid2.velocity = ship.GetComponent<Rigidbody>().velocity + (transform.right * -_missileSpeed);
    56.         Destroy(missile2, lifeTime);
    57.  
    58.         Rigidbody rigid3 = missile3.GetComponent<Rigidbody>();
    59.         rigid3.velocity = ship.GetComponent<Rigidbody>().velocity + (transform.right * -_missileSpeed);
    60.         Destroy(missile3, lifeTime);
    61.  
    62.         NetworkServer.Spawn(missile);
    63.         NetworkServer.Spawn(missile1);
    64.         NetworkServer.Spawn(missile2);
    65.         NetworkServer.Spawn(missile3);
    66.     }
    67.  
    68.      
    69.   [Command]
    70.     void CmdDoFireO(float lifeTime)
    71.     {
    72.  
    73.         missile4 = (GameObject)Instantiate(_missilePrefab, _missileSpawnPoint4.position, Quaternion.identity);
    74.  
    75.         missile5 = (GameObject)Instantiate(_missilePrefab, _missileSpawnPoint5.position, Quaternion.identity);
    76.  
    77.         missile6 = (GameObject)Instantiate(_missilePrefab, _missileSpawnPoint6.position, Quaternion.identity);
    78.  
    79.         missile7 = (GameObject)Instantiate(_missilePrefab, _missileSpawnPoint7.position, Quaternion.identity);
    80.  
    81.         Rigidbody rigid = missile4.GetComponent<Rigidbody>();
    82.         rigid.velocity = ship.GetComponent<Rigidbody>().velocity + (transform.right * _missileSpeed);
    83.         Destroy(missile4, lifeTime);
    84.  
    85.         Rigidbody rigid1 = missile5.GetComponent<Rigidbody>();
    86.         rigid1.velocity = ship.GetComponent<Rigidbody>().velocity + (transform.right * _missileSpeed);
    87.         Destroy(missile5, lifeTime);
    88.  
    89.         Rigidbody rigid2 = missile6.GetComponent<Rigidbody>();
    90.         rigid2.velocity = ship.GetComponent<Rigidbody>().velocity + (transform.right * _missileSpeed);
    91.         Destroy(missile6, lifeTime);
    92.  
    93.         Rigidbody rigid3 = missile7.GetComponent<Rigidbody>();
    94.         rigid3.velocity = ship.GetComponent<Rigidbody>().velocity + (transform.right * _missileSpeed);
    95.         Destroy(missile7, lifeTime);
    96.  
    97.         NetworkServer.Spawn(missile4);
    98.         NetworkServer.Spawn(missile5);
    99.         NetworkServer.Spawn(missile6);
    100.         NetworkServer.Spawn(missile7);
    101.     }
     
    Last edited: Dec 11, 2015
  2. DRRosen3

    DRRosen3

    Joined:
    Jan 30, 2014
    Posts:
    683
    Firstly, you're re-writing too much code. You need to wrap your spawn process in a function of itself, like this:
    Code (CSharp):
    1. public void MissileFire(Vector3 _spawnPosition)
    2. {
    3.         GameObject missile = (GameObject)Instantiate(_missilePrefab, _spawnPosition, Quaternion.identity);
    4.  
    5.         missile.GetComponent<Rigidbody>().velocity = ship.GetComponent<Rigidbody>().velocity + (transform.right * _missleSpeed);
    6.        Destroy(missile, lifeTime);
    7. }
    Then, inside your Command(s) just call the function.
    Code (CSharp):
    1. [Command]
    2. public void CmdMissileFireV()
    3. {
    4.         MissileFire(missleSpawnPoint1.position);
    5.         MissileFire(missleSpawnPoint2.position);
    6.         MissileFire(missleSpawnPoint3.position);
    7.         MissileFire(missleSpawnPoint4.position);
    8. }
    9. [Command]
    10. public void CmdMissileFireO()
    11. {
    12.         MissileFire(missleSpawnPoint5.position);
    13.         MissileFire(missleSpawnPoint6.position);
    14.         MissileFire(missleSpawnPoint7.position);
    15.         MissileFire(missleSpawnPoint8.position);
    16. }
    2. Now to your problem. Does this work for the client or just for the server? If player A starts the game, and player B joins the game...and player B tries to fire missiles, does it work on player B's computer?
     
  3. Raatopojat

    Raatopojat

    Joined:
    May 9, 2014
    Posts:
    10
    The idea is that my ship has 4 cannons both sides of ship. Then if Q is clicked it shoots left side cannons and E opposite side. Every cannon has it's own spawn point where cannonballs (missiles in my code) are spawned. Is that possible to make happen with wrapping the code like that?
    In my code (at first post) it didn't matter if user was Client or Server, both worked only in its own screen but instantiated them well there. So network didn't success there.

    I tried to replace [command] to [client]. In that case missiles what i shot from B (client) screen, seem on server screen (A).
    But that case didn't work another way. Server (A) shots seem only its own screen and client (B) didn't see them.

    Did that clarify the situation any better?
    And thanks for the reply!
     
  4. DRRosen3

    DRRosen3

    Joined:
    Jan 30, 2014
    Posts:
    683
    To your question, yes it will work. I simply simplified your code. Where you had written almost 70 lines of code, I did the same thing in 23 lines.

    Back to the issue. I can't see what might be causing the issue.
     
  5. Raatopojat

    Raatopojat

    Joined:
    May 9, 2014
    Posts:
    10
    Thank you for taking the time to look at our problem and helping us clean our code. We managed to solve the problem with a few small changes.


    Code (CSharp):
    1.    public void MissileFireV(Vector3 _spawnPosition)
    2.     {
    3.         GameObject missile = (GameObject)Instantiate(_missilePrefab, _spawnPosition, Quaternion.identity);
    4.  
    5.         missile.GetComponent<Rigidbody>().velocity = ship.GetComponent<Rigidbody>().velocity + (transform.right * -_missileSpeed);
    6.         NetworkServer.Spawn(missile);
    7.         Destroy(missile, 2.5f);
    8.     }
    9.     public void MissileFireO(Vector3 _spawnPosition)
    10.     {
    11.         GameObject missile = (GameObject)Instantiate(_missilePrefab2, _spawnPosition, Quaternion.identity);
    12.  
    13.         missile.GetComponent<Rigidbody>().velocity = ship.GetComponent<Rigidbody>().velocity + (transform.right * _missileSpeed);
    14.         NetworkServer.Spawn(missile);
    15.         Destroy(missile, 2.5f);
    16.     }
    17.  
    18.  
    19.     [Command]
    20.     public void CmdMissileFireV()
    21.     {
    22.         MissileFireV(_missileSpawnPoint1.position);
    23.         MissileFireV(_missileSpawnPoint2.position);
    24.         MissileFireV(_missileSpawnPoint3.position);
    25.         MissileFireV(_missileSpawnPoint4.position);
    26.     }
    27.     [Command]
    28.     public void CmdMissileFireO()
    29.     {
    30.         MissileFireO(_missileSpawnPoint5.position);
    31.         MissileFireO(_missileSpawnPoint6.position);
    32.         MissileFireO(_missileSpawnPoint7.position);
    33.         MissileFireO(_missileSpawnPoint8.position);
    34.     }
    35.    
    Adding "NetworkServer.Spawn(missile);" was the thing that made the difference.
     
  6. DRRosen3

    DRRosen3

    Joined:
    Jan 30, 2014
    Posts:
    683
    That's weird, because you already had NetworkServer.Spawn() in your original code.