Search Unity

  1. We are migrating the Unity Forums to Unity Discussions. On July 12, the Unity Forums will become read-only. On July 15, Unity Discussions will become read-only until July 18, when the new design and the migrated forum contents will go live. Read our full announcement for more information and let us know if you have any questions.

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:
    19
    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:
    19
    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.