Health Bar UI not updating

Hello. I am developing an FPS multiplayer game based on NGO. I have created a simple health bar system using a Slider object, which is placed inside the Canvas, and the Canvas is a child of the Player prefab. Till now, everything good. When the player gets shot, his health is reduced, and when debugging, i can see that every player has the correct health.

The problem arises when i try to update the health bar of each player. I’ve followed some tutorials, where you Destroy the Canvas object,if the IsOwner variable is false, in order not to have multiple UI’s on top of each other.

The health bar updates perfectly for the Host, but for the Clients, it does not.

 public override void OnNetworkSpawn()
    {
        current = MaxHealth;
        slider.value = MaxHealth;
        slider.maxValue = MaxHealth;

        if (!IsOwner)
        {
            Destroy(ui);
        }

        if (!IsServer) { return; }

        CurrentHealth.Value = MaxHealth;
    }

    public void TakeDamage(int damageValue)
    {
        ModifyHealth(-damageValue);
     }

    private void ModifyHealth(int value)
    {
        if (isDead) { return; }

        int newHealth = CurrentHealth.Value + value;
        CurrentHealth.Value = Mathf.Clamp(newHealth, 0, MaxHealth);
        slider.value = current;
        
        if (CurrentHealth.Value == 0)
        {
            OnDie?.Invoke(this);
            isDead = true;
        }
    }

Without seeing the rest of your class, I am going to guess that you are using a NetworkVariable for the CurrentHealth property?
Based on the snippet of code you posted, I am guessing each owner is updating their health bar? If so, then you should make sure that it is initialized with owner write permissions. I ran with your code snippet and provided a fully implemented “PlayerHealth” NetworkBehaviour component as an example:

using System;
using Unity.Netcode;
using UnityEngine;
using UnityEngine.UIElements;

public class PlayerHealth : NetworkBehaviour
{
    public int MaxHealth = 100;
    public NetworkVariable<int> CurrentHealth = new NetworkVariable<int>(default,
        NetworkVariableReadPermission.Everyone, NetworkVariableWritePermission.Owner);
    private Slider m_Slider;
    private bool m_IsPlayerDead => CurrentHealth.Value == 0;
    public Action<PlayerHealth> OnDie;
    private void Awake()
    {
        m_Slider = GetComponent<Slider>();
    }
    public override void OnNetworkSpawn()
    {
        if (IsOwner)
        {
            CurrentHealth.Value = MaxHealth;
        }
        base.OnNetworkSpawn();
    }
    public void TakeDamage(int damageValue)
    {
        if (!IsOwner || m_IsPlayerDead)
        {
            return;
        }
        CurrentHealth.Value = Mathf.Clamp(CurrentHealth.Value - damageValue, 0, MaxHealth);
        if (m_IsPlayerDead)
        {
            OnDie?.Invoke(this);
        }
    }
    private void OnGUI()
    {
        if (m_IsPlayerDead)
        {
            // Optionally, when the player is dead display something else here in place of the health
        }
        else
        {
            // Just always update health bar based on CurrentHealth
            m_Slider.value = CurrentHealth.Value;
        }
    }
}

With maybe some minor adjustments, this should “just work”. You don’t need to disable the sliders for non-players.
However, I might suggest searching for: “Unity create health bar with image that is assigned a sprite”
You can accomplish the same kind of effect using an image that has a sprite assigned to it and the Image Type is set to filled. Then you can adjust the fill amount to increase or decrease the amount of the image filled by the sprite.

Let me know if this resolves your issue?

Hello @NoelStephens_Unity , sorry for not answering for many days, i did not have the time to work on my game unfortunately.

and yes your logic works, i followed the same logic and applied it to my game, and it now works properly. Thanks again!

1 Like