Search Unity

  1. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Question Health Bar UI not updating

Discussion in 'Netcode for GameObjects' started by DimNik97, Nov 22, 2023.

  1. DimNik97

    DimNik97

    Joined:
    Oct 19, 2022
    Posts:
    11
    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.



    Code (CSharp):
    1.  public override void OnNetworkSpawn()
    2.     {
    3.         current = MaxHealth;
    4.         slider.value = MaxHealth;
    5.         slider.maxValue = MaxHealth;
    6.  
    7.         if (!IsOwner)
    8.         {
    9.             Destroy(ui);
    10.         }
    11.  
    12.         if (!IsServer) { return; }
    13.  
    14.         CurrentHealth.Value = MaxHealth;
    15.     }
    16.  
    17.     public void TakeDamage(int damageValue)
    18.     {
    19.         ModifyHealth(-damageValue);
    20.      }
    21.  
    22.     private void ModifyHealth(int value)
    23.     {
    24.         if (isDead) { return; }
    25.  
    26.         int newHealth = CurrentHealth.Value + value;
    27.         CurrentHealth.Value = Mathf.Clamp(newHealth, 0, MaxHealth);
    28.         slider.value = current;
    29.        
    30.         if (CurrentHealth.Value == 0)
    31.         {
    32.             OnDie?.Invoke(this);
    33.             isDead = true;
    34.         }
    35.     }
     
    Last edited: Nov 22, 2023
  2. NoelStephens_Unity

    NoelStephens_Unity

    Unity Technologies

    Joined:
    Feb 12, 2022
    Posts:
    244
    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:

    Code (CSharp):
    1.  
    2. using System;
    3. using Unity.Netcode;
    4. using UnityEngine;
    5. using UnityEngine.UIElements;
    6.  
    7. public class PlayerHealth : NetworkBehaviour
    8. {
    9.     public int MaxHealth = 100;
    10.     public NetworkVariable<int> CurrentHealth = new NetworkVariable<int>(default,
    11.         NetworkVariableReadPermission.Everyone, NetworkVariableWritePermission.Owner);
    12.     private Slider m_Slider;
    13.     private bool m_IsPlayerDead => CurrentHealth.Value == 0;
    14.     public Action<PlayerHealth> OnDie;
    15.     private void Awake()
    16.     {
    17.         m_Slider = GetComponent<Slider>();
    18.     }
    19.     public override void OnNetworkSpawn()
    20.     {
    21.         if (IsOwner)
    22.         {
    23.             CurrentHealth.Value = MaxHealth;
    24.         }
    25.         base.OnNetworkSpawn();
    26.     }
    27.     public void TakeDamage(int damageValue)
    28.     {
    29.         if (!IsOwner || m_IsPlayerDead)
    30.         {
    31.             return;
    32.         }
    33.         CurrentHealth.Value = Mathf.Clamp(CurrentHealth.Value - damageValue, 0, MaxHealth);
    34.         if (m_IsPlayerDead)
    35.         {
    36.             OnDie?.Invoke(this);
    37.         }
    38.     }
    39.     private void OnGUI()
    40.     {
    41.         if (m_IsPlayerDead)
    42.         {
    43.             // Optionally, when the player is dead display something else here in place of the health
    44.         }
    45.         else
    46.         {
    47.             // Just always update health bar based on CurrentHealth
    48.             m_Slider.value = CurrentHealth.Value;
    49.         }
    50.     }
    51. }
    52.  
    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?
     
  3. DimNik97

    DimNik97

    Joined:
    Oct 19, 2022
    Posts:
    11
    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!
     
    NoelStephens_Unity likes this.