MIRROR HealthController for player and Monster

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

public class HealthController : NetworkBehaviour
{

     enum TypeController
       {
           Player, Enemy
       }

[SerializeField] private TypeController typeController;
[SerializeField] protected Slider _healthSliderRpc;
[SerializeField] protected TMP_Text _textHealth;

[SyncVar(hook = nameof(SyncHealth))]
    private float _SyncHealth;

[SerializeField] protected float _currentHealth;

public virtual float currentHealth
    {
        get
        {
            return _currentHealth;
        }
        protected set
        {
            if (_currentHealth != value)
                _currentHealth = value;
        }
    }

void SyncHealth(float oldvalue, float newValue)
    {
        currentHealth = newValue;
      
        _healthSliderRpc.DOValue(newValue / 100, Time.deltaTime * 20);

        if(typeController == TypeController.Enemy)
            _textHealth.text = $"{newValue}/{MaxHealth}";
    }

protected void ClientServerChangeHp(float hp)
    {
        if (isServer) ChangeHealthValue(hp);
        else CmdChangeHealth(hp);
    }

[Server]
    public void ChangeHealthValue(float newValue)
    {
        _SyncHealth = newValue;
    }

[Command]
    public void CmdChangeHealth(float newValue)
    {
        ChangeHealthValue(newValue);
    }

public virtual void TakeDamage(Damage damage)
    {
        if (typeController == TypeController.Player)
        {
            if (hasAuthority)
            {
                Debug.LogWarning("Damage take Player");
                if (damage != null)
                {
                   
                    if (currentHealth > 0)
                    {
                        ClientServerChangeHp(currentHealth - damage.damageValue);
                    }
                }
            }
        }

        else
        {
            Debug.LogWarning("Damage take Enemy");
            if (damage != null)
            {
              
                if (currentHealth > 0)
                {
                    _SyncHealth -= damage.damageValue;
                }
            }
        }
}

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

solved

public virtual void TakeDamage(Damage damage)
    {
        if (damage != null)
        {
            if (currentHealth > 0 )
            {
                if (isServer)
                    _SyncHealth -= damage.damageValue;
                else
                {
                    if (hasAuthority)
                    {
                        CmdChangeHealth(currentHealth - damage.damageValue);
                    }
                }
            }
        }
    }
1 Like