Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Third Party MIRROR HealthController for player and Monster

Discussion in 'Multiplayer' started by anomal3, Dec 5, 2022.

  1. anomal3

    anomal3

    Joined:
    Mar 11, 2017
    Posts:
    14
    Good day everyone.
    I have a problem that I can't figure out.

    I wrote a health controller that I want to use on players and monsters
    I inherit this class from both the character and the monster

    I use a separate server and connect clients to it.
    None of the clients is a server

    Code (CSharp):
    1.  
    2. public class HealthController : NetworkBehaviour
    3. {
    4.  
    5.      enum TypeController
    6.        {
    7.            Player, Enemy
    8.        }
    9.  
    10. [SerializeField] private TypeController typeController;
    11. [SerializeField] protected Slider _healthSliderRpc;
    12. [SerializeField] protected TMP_Text _textHealth;
    13.  
    14. [SyncVar(hook = nameof(SyncHealth))]
    15.     private float _SyncHealth;
    16.  
    17. [SerializeField] protected float _currentHealth;
    18.  
    19. public virtual float currentHealth
    20.     {
    21.         get
    22.         {
    23.             return _currentHealth;
    24.         }
    25.         protected set
    26.         {
    27.             if (_currentHealth != value)
    28.                 _currentHealth = value;
    29.         }
    30.     }
    31.  
    32. void SyncHealth(float oldvalue, float newValue)
    33.     {
    34.         currentHealth = newValue;
    35.      
    36.         _healthSliderRpc.DOValue(newValue / 100, Time.deltaTime * 20);
    37.  
    38.         if(typeController == TypeController.Enemy)
    39.             _textHealth.text = $"{newValue}/{MaxHealth}";
    40.     }
    41.  
    42. protected void ClientServerChangeHp(float hp)
    43.     {
    44.         if (isServer) ChangeHealthValue(hp);
    45.         else CmdChangeHealth(hp);
    46.     }
    47.  
    48. [Server]
    49.     public void ChangeHealthValue(float newValue)
    50.     {
    51.         _SyncHealth = newValue;
    52.     }
    53.  
    54. [Command]
    55.     public void CmdChangeHealth(float newValue)
    56.     {
    57.         ChangeHealthValue(newValue);
    58.     }
    59.  
    60. public virtual void TakeDamage(Damage damage)
    61.     {
    62.         if (typeController == TypeController.Player)
    63.         {
    64.             if (hasAuthority)
    65.             {
    66.                 Debug.LogWarning("Damage take Player");
    67.                 if (damage != null)
    68.                 {
    69.                    
    70.                     if (currentHealth > 0)
    71.                     {
    72.                         ClientServerChangeHp(currentHealth - damage.damageValue);
    73.                     }
    74.                 }
    75.             }
    76.         }
    77.  
    78.         else
    79.         {
    80.             Debug.LogWarning("Damage take Enemy");
    81.             if (damage != null)
    82.             {
    83.              
    84.                 if (currentHealth > 0)
    85.                 {
    86.                     _SyncHealth -= damage.damageValue;
    87.                 }
    88.             }
    89.         }
    90. }
    The player's health is not always taken into account, although there is a hit.
    The health of the spider lags terribly.

    On one client, with 3 hits, the text does not change and the health bar too
    On other client it is displayed well.

    I must be missing something and I don't understand it.

    Reading the documentation and starting from the problems on the forums, I can not come to some correct solution.

    Please help me solve the problem
     
  2. anomal3

    anomal3

    Joined:
    Mar 11, 2017
    Posts:
    14
    solved

    Code (CSharp):
    1. public virtual void TakeDamage(Damage damage)
    2.     {
    3.         if (damage != null)
    4.         {
    5.             if (currentHealth > 0 )
    6.             {
    7.                 if (isServer)
    8.                     _SyncHealth -= damage.damageValue;
    9.                 else
    10.                 {
    11.                     if (hasAuthority)
    12.                     {
    13.                         CmdChangeHealth(currentHealth - damage.damageValue);
    14.                     }
    15.                 }
    16.             }
    17.         }
    18.     }
     
    mischa2k likes this.