Search Unity

Third Party Having issues with respawning a player with Mirror Networking

Discussion in 'Multiplayer' started by r3dst0rm1337, Aug 23, 2021.

  1. r3dst0rm1337

    r3dst0rm1337

    Joined:
    Jun 8, 2017
    Posts:
    2
    I'm trying to let a player respawn after he's dead. The respawn mechanism should use a location X as a spawn point. With my code, a player sometimes respawn at location X and sometimes at the same location where he died (it can also be noticed some sort of porting for a small fraction of a second, the player starts at location X but is instantly 'teleported').

    My Player Prefab, has Client Authority, to keep things simple for now.

    The respawn basically should: hide the players gameobject, reset it to position X and displays the players gameobject again.

    I'm hoping someone can point me in the right direction on where I mess up.

    Thank you guys in advance!

    This is what I've came up with:

    Code (CSharp):
    1.  
    2. // PlayerShoot.cs
    3.  
    4. using Mirror;
    5. using Types;
    6. using UnityEngine;
    7.  
    8. namespace Player
    9. {
    10.     public class PlayerShoot : NetworkBehaviour
    11.     {
    12.         private const string PLAYER_TAG = "Player";
    13.  
    14.         [SerializeField] private Camera firstPersonCamera;
    15.         [SerializeField] private LayerMask layerMask;
    16.  
    17.         public override void OnStartLocalPlayer()
    18.         {
    19.             firstPersonCamera = PlayerCamera.GetCamera();
    20.         }
    21.  
    22.         private void Update()
    23.         {
    24.             if (Input.GetButtonDown("Fire1"))
    25.             {
    26.                 var fireRate = 1f / 1f;
    27.                 InvokeRepeating(nameof(Shoot), 0f, fireRate);
    28.             }
    29.             else if (Input.GetButtonUp("Fire1"))
    30.             {
    31.                 // Cancel shoot
    32.                 CancelInvoke(nameof(Shoot));
    33.             }
    34.         }
    35.  
    36.  
    37.         [Client]
    38.         void Shoot()
    39.         {
    40.             if (!isLocalPlayer)
    41.             {
    42.                 return;
    43.             }
    44.  
    45.             RaycastHit _hit;
    46.             var weaponDistance = 20f;
    47.             if (Physics.Raycast(firstPersonCamera.transform.position, firstPersonCamera.transform.forward, out _hit, weaponDistance))
    48.             {
    49.                 if (_hit.collider.CompareTag(PLAYER_TAG))
    50.                 {
    51.                     var damage = 10;
    52.                     var shooterConnectionID = GetComponent<NetworkIdentity>().netId.ToString();
    53.                     var target = _hit.collider.gameObject.GetComponent<NetworkIdentity>().netId.ToString();
    54.                     CmdPlayerShot(target, damage, shooterConnectionID);
    55.                 }
    56.             }
    57.         }
    58.  
    59.         [Command]
    60.         void CmdPlayerShot(string target, int damage, string shooterConnectionID)
    61.         {
    62.             var player = GameManager.GameManager.GetPlayerByConnectionID(new ConnectionID(target));
    63.             player.RpcTakeDamage(damage, shooterConnectionID);
    64.         }
    65.     }
    66. }
    Code (CSharp):
    1.  
    2. // Player.cs
    3. using System.Collections;
    4. using System.Linq;
    5. using Mirror;
    6. using Types;
    7. using UnityEngine;
    8.  
    9. namespace Player
    10. {
    11.     public class Player : NetworkBehaviour
    12.     {
    13.         [SerializeField] private TextMesh playerName;
    14.         [SerializeField] private GameObject floatingPlayerInformation;
    15.         [SerializeField] private GameObject cameraMountPoint;
    16.         [SerializeField] private float movementSpeed = 4.0f;
    17.         [SerializeField] private GameObject[] disableUponDeath;
    18.  
    19.         [SyncVar(hook = nameof(OnNameChanged))]
    20.         public string userName;
    21.         [SyncVar] private int currentHealth = 100;
    22.         [SyncVar] private bool isDead = false;
    23.  
    24.         #region Player Statistics
    25.         [SyncVar] private int kills = 0;
    26.         [SyncVar] private int deaths = 0;
    27.         #endregion
    28.  
    29.         public override void OnStartLocalPlayer()
    30.         {
    31.             base.OnStartLocalPlayer();
    32.             SetupCamera();
    33.         }
    34.  
    35.         private void SetupCamera()
    36.         {
    37.             if (!isLocalPlayer)
    38.             {
    39.                 return;
    40.             }
    41.            
    42.             var cameraTransform = PlayerCamera.GetCamera().gameObject.transform;
    43.             cameraTransform.parent = cameraMountPoint.transform;
    44.             cameraTransform.position = cameraMountPoint.transform.position;
    45.             cameraTransform.rotation = cameraMountPoint.transform.rotation;
    46.         }
    47.  
    48.         private void Update()
    49.         {
    50.             if (!isLocalPlayer)
    51.             {
    52.                 floatingPlayerInformation.transform.LookAt(PlayerCamera.GetCamera().transform);
    53.                 // Return as this is now client authority
    54.             }
    55.         }
    56.  
    57.         private void OnNameChanged(string oldValue, string newValue)
    58.         {
    59.             playerName.text = userName;
    60.         }
    61.  
    62.         [ClientRpc]
    63.         public void RpcTakeDamage(int damageAmount, string shooterConnectionID)
    64.         {
    65.             currentHealth -= damageAmount;
    66.  
    67.             Debug.Log(userName + " now has " + currentHealth + " health.");
    68.  
    69.             if (currentHealth <= 0)
    70.             {
    71.                 Die(shooterConnectionID);
    72.             }
    73.         }
    74.  
    75.         private void Die(string killer)
    76.         {
    77.             isDead = true;
    78.             var playerKiller = GameManager.GameManager.GetPlayerByConnectionID(new ConnectionID(killer));
    79.  
    80.             IncreaseKillsForKiller(playerKiller);
    81.             SpectateWorldWhileDead();
    82.             HideGameObjectsUponDeath();
    83.             IncreaseDeathCounter();
    84.  
    85.             StartCoroutine(Respawn());
    86.         }
    87.  
    88.         private void IncreaseKillsForKiller(Player killer)
    89.         {
    90.             killer.kills++;
    91.         }
    92.        
    93.         private IEnumerator Respawn ()
    94.         {
    95.             yield return new WaitForSeconds(5f);
    96.  
    97.             var spawnPoint = new Vector3(23f, 0.75f, 0f);
    98.             transform.position = spawnPoint;
    99.             transform.rotation = Quaternion.identity;
    100.  
    101.             yield return new WaitForSeconds(0.1f);
    102.  
    103.             ShowGameObjectsUponRespawn();
    104.             SetDefaultValues();
    105.             SetupCamera();
    106.  
    107.             Debug.Log(userName + " respawned.");
    108.         }
    109.  
    110.         private void SetDefaultValues()
    111.         {
    112.             currentHealth = 100;
    113.             isDead = false;
    114.         }
    115.  
    116.         private void IncreaseDeathCounter()
    117.         {
    118.             deaths++;
    119.         }
    120.  
    121.         private void HideGameObjectsUponDeath()
    122.         {
    123.             foreach (var item in disableUponDeath)
    124.             {
    125.                 item.SetActive(false);
    126.             }
    127.         }
    128.  
    129.         private void ShowGameObjectsUponRespawn()
    130.         {
    131.             foreach (var item in disableUponDeath)
    132.             {
    133.                 item.SetActive(true);
    134.             }
    135.         }
    136.  
    137.         private void SpectateWorldWhileDead()
    138.         {
    139.             if (!isLocalPlayer)
    140.             {
    141.                 return;
    142.             }
    143.             var playerSpectateMountPoint = GameObject.FindGameObjectsWithTag("SpectatePoint").ToList().First();
    144.             var playerCameraTransform = PlayerCamera.GetCamera().gameObject.transform;
    145.             playerCameraTransform.position = playerSpectateMountPoint.transform.position;
    146.             playerCameraTransform.rotation = playerSpectateMountPoint.transform.rotation;
    147.         }
    148.  
    149.         public bool IsDead()
    150.         {
    151.             return isDead;
    152.         }
    153.     }
    154. }
     
  2. r3dst0rm1337

    r3dst0rm1337

    Joined:
    Jun 8, 2017
    Posts:
    2
    I solved the issue by also disabling the character controller component attached to my player. This solves the inconsistency when moving a player when respawning
     
  3. lem123

    lem123

    Joined:
    May 3, 2020
    Posts:
    1
    This fixed my issue as well, thanks!