Search Unity

Few issues, need clarification on what I'm doing wrong

Discussion in 'Multiplayer' started by Foestar, Sep 27, 2018.

  1. Foestar

    Foestar

    Joined:
    Aug 12, 2013
    Posts:
    350
    So I was sad to read while posting this that the UNet features will soon be deprecated along with P2P services shortly down the road, and sincerely hope their replacement will be equal to or far better. But seeing the changes as they've done (short of the asset store and forum changes) I've mostly agreed and enjoyed their changes over the past "eleventy" billion patches. o_O:D

    With that said, I still plan on continuing my current project and have enjoyed my progress thus far with UNet and it's current rewards it has given me and my project. I am however finding myself with a few minor bugs atm that I can't seem to figure out. So I thought I would ask for some help in what I am doing wrong and how I should go about my current issues.

    So the first problem is I have a code that will allow the player to shoot, take damage, etc. The issue I have is when the player shoots we send out a raycast and if the ray hits a player we do a blood particle, otherwise we do debris. This works as intended visually per player, only I noticed one small issue: When you get shot by another player they see the proper particles but you do not. The sparks/debris plays instead. Now I'm thinking this is due to something about the clients, but not positive how. This is the ClientRpc for the section I'm talking about.

    Code (CSharp):
    1. [ClientRpc]
    2.     void RpcDoHitEffect(Vector3 _pos, Vector3 _normal)
    3.     {
    4.         //create a raycast variable
    5.         RaycastHit _playerhit;
    6.  
    7.         //create the ray out of the ray cast forward from player camera
    8.         if (Physics.Raycast(cam.transform.position, cam.transform.forward, out _playerhit, currentWeapon.range, mask))
    9.         {
    10.  
    11.             //if we hit the player, blood sprays, otherwise it's debris
    12.             if (_playerhit.collider.tag == PLAYER_TAG)
    13.             {
    14.                 GameObject _hitEffect = (GameObject)Instantiate(weaponManager.GetCurrentGraphics().hitBodyEffectPrefab, _pos, Quaternion.LookRotation(_normal));
    15.                 //look into object pooling if instantiating this many objects with machine guns becomes a performance issue
    16.                 Destroy(_hitEffect, 2f);
    17.             }
    18.             else
    19.             {
    20.                 GameObject _hitEffect = (GameObject)Instantiate(weaponManager.GetCurrentGraphics().hitEffectPrefab, _pos, Quaternion.LookRotation(_normal));
    21.                 Destroy(_hitEffect, 2f);
    22.             }
    23.              
    24.         }
    25.  
    26.     }
     
    Last edited: Sep 27, 2018
  2. Foestar

    Foestar

    Joined:
    Aug 12, 2013
    Posts:
    350
    Putting this in two posts in the same thread so it's two separate questions rather than one long wall of text that almost seems like one.

    But my second problem is with raising and lowering my players graphics. I think this has something to do with my function acting out twice from the host. So when a player dies on the separate machine (not the host) their graphic lowers slightly so the animation that is playing looks more natural. Then after they respawn the graphic is raised back up to it's basic Idle/Run position.

    The problem however is when this sequence is done on the host machine the players who get killed lower x2 and I'm assuming raise x2 because it ends up back where it's supposed too at the end. I've tried several things to get around this but figured it would be better to do it the right way by asking for help/advice on here.

    Even though UNet will be a thing of the past I'd still like to have a better understanding and better habbits for it while it's here and I"m using it. Anywho, here is my code for that part.

    Code (CSharp):
    1. [ClientRpc]
    2.     public void RpcTakeDamage (int _amount)
    3.     {
    4.         if (isDead)
    5.             return;
    6.  
    7.         currentHealth -= _amount;
    8.  
    9.         Debug.Log(transform.name + " now has " + currentHealth + " health.");
    10.  
    11.         if (currentHealth <= 0)
    12.         {
    13.             Die();
    14.         }
    15.     }
    16.  
    17.     private void Die ()
    18.     {
    19.         isDead = true;
    20.  
    21.         //disable components
    22.         for (int i = 0; i < disableOnDeath.Length; i++)
    23.         {
    24.             disableOnDeath[i].enabled = false;
    25.         }
    26.  
    27.         //disable collider
    28.         //if the collider is gone but gravity is still on we fall, so remove this effect
    29.         Collider _col = GetComponent<Collider>();
    30.         if (_col != null)
    31.         {
    32.             _col.enabled = false;
    33.             this.GetComponent<Rigidbody>().useGravity = false;
    34.             playerAnim.SetBool("isDead", true);
    35.         }
    36.  
    37.         //spawn a death effect
    38.         GameObject _gfxIns = (GameObject)Instantiate(deathEffect, transform.position, Quaternion.identity);
    39.         Destroy(_gfxIns, 3f);
    40.  
    41.         Debug.Log(transform.name + " is DEAD!");
    42.  
    43.         StartCoroutine(Respawn());
    44.  
    45.         CmdLowerPlayerGraphics();
    46.  
    47.     }
    48.  
    49.     private IEnumerator Respawn ()
    50.     {
    51.         yield return new WaitForSeconds(GameManager.instance.matchSettings.respawnTime);
    52.  
    53.         SetDefaults();
    54.         Transform _spawnPoint = NetworkManager.singleton.GetStartPosition();
    55.         transform.position = _spawnPoint.position;
    56.         transform.rotation = _spawnPoint.rotation;
    57.  
    58.         Debug.Log(transform.name + " respawned.");
    59.  
    60.         CmdResetPlayerGraphics();
    61.     }
    62.  
    63.     [Command]
    64.     private void CmdResetPlayerGraphics()
    65.     {
    66.         RpcPlayerGraphicsReseted();
    67.     }
    68.    
    69.     [ClientRpc]
    70.     private void RpcPlayerGraphicsReseted()
    71.     {
    72.         //raise the graphics so player is off the ground
    73.         playerGraphics.Translate(0, 0.45f, 0, Space.Self);
    74.  
    75.         Collider _col2 = GetComponent<Collider>();
    76.         _col2.enabled = true;
    77.     }
    78.  
    79.     [Command]
    80.     private void CmdLowerPlayerGraphics()
    81.     {
    82.         RpcPlayerGraphicsLowered();
    83.     }
    84.  
    85.     [ClientRpc]
    86.     private void RpcPlayerGraphicsLowered()
    87.     {
    88.         //lower the graphics so player is on the ground
    89.         playerGraphics.Translate(0, -0.45f, 0, Space.Self);
    90.     }
    91.  
    92.     public void SetDefaults()
    93.     {
    94.  
    95.         isDead = false;
    96.  
    97.         currentHealth = maxHealth;
    98.  
    99.         for (int i = 0; i < disableOnDeath.Length; i++)
    100.         {
    101.             disableOnDeath[i].enabled = wasEnabled[i];
    102.         }
    103.  
    104.         Collider _col = GetComponent<Collider>();
    105.         if(_col != null)
    106.         {
    107.             _col.enabled = true;
    108.             this.GetComponent<Rigidbody>().useGravity = true;
    109.             playerAnim.SetBool("isDead", false);
    110.         }
    111.  
    112.     }
     
  3. Munchy2007

    Munchy2007

    Joined:
    Jun 16, 2013
    Posts:
    1,735
    I sounds like the lower graphics function is running not only when it receives its message to lower but also when other clients in the scene receive their message to lower the graphics. You can test this by playing with 3 clients, and if the lower amount is 3x then that confirms it.

    You're probably just missing an isLocalPlayer check in the RPC function to ensure it only runs on the script of the player that the message is targeted at.