Search Unity

  1. Unity 6 Preview is now available. To find out what's new, have a look at our Unity 6 Preview blog post.
    Dismiss Notice
  2. Unity is excited to announce that we will be collaborating with TheXPlace for a summer game jam from June 13 - June 19. Learn more.
    Dismiss Notice

Health Bar UI Issues [SOLVED]

Discussion in 'UGUI & TextMesh Pro' started by SkyTech6, Jul 14, 2015.

  1. SkyTech6

    SkyTech6

    Joined:
    Jul 14, 2015
    Posts:
    151
    Hey guys and gals, I'm trying to create a health bar in my game, I've tried a LOT of different things. Perhaps someone else will be able to figure it out?

    No matter what I do, when I start the game and the player takes damage his Health Bar instantly drops to zero instead of increments. Even upon death/respawn, it doesn't restart the health bar at full.

    Code (csharp):
    1.  
    2. using UnityEngine;
    3. using System.Collections;
    4.  
    5. public class Player : MonoBehaviour {
    6.  
    7.     [System.Serializable]
    8.     public class PlayerStats {
    9.         public int max_Health = 100;
    10.         public int cur_Health = 0;
    11.         public GameObject[] Ammo;
    12.     }
    13.  
    14.     public PlayerStats playerStats = new PlayerStats();
    15.  
    16.     public int fallBoundary = -20;
    17.  
    18.     public GameObject healthBar;
    19.  
    20.     void Start () {
    21.  
    22.         playerStats.cur_Health = playerStats.max_Health;
    23.         InvokeRepeating ("decreasehealth",1f,1f);
    24.  
    25.     }
    26.  
    27.     void Update () {
    28.         if (transform.position.y <= fallBoundary)
    29.         {
    30.             DamagePlayer (999999999);
    31.             Debug.Log("PLAYER DEAD - BOUNDARY FALL");
    32.         }
    33.      
    34.         if (playerStats.cur_Health <= 0) {
    35.             GameMaster.KillPlayer (this);
    36.             Debug.Log ("KILL PLAYER");
    37.         }
    38.  
    39.     }
    40.  
    41.     public void DamagePlayer (int damage) {
    42.         playerStats.cur_Health -= damage;
    43.  
    44.     }
    45.     void decreasehealth(){
    46.         playerStats.cur_Health -= 10;
    47.         float calc_Health = playerStats.cur_Health / playerStats.max_Health;
    48.         SetHealthBar (calc_Health);
    49.     }
    50.  
    51.     public void SetHealthBar(float myHealth){
    52.  
    53.     healthBar.transform.localScale = new Vector3(myHealth, healthBar.transform.localScale.y, healthBar.transform.localScale.z);
    54.     }
    55. }
    56.  
    57.  
    Screen Shot 2015-07-14 at 1.37.19 AM.png
    There's the inspector.
    Screen Shot 2015-07-14 at 1.59.58 AM.png
    (FIXED..kinda)That's what the debugger says after the player has respawned and the health bar remains zero'd.

    Major thanks to anyone willing to lend me a hand, I'll owe you one.
    Also, hey community, nice to meet you all.
     
    Last edited: Jul 14, 2015
  2. larku

    larku

    Joined:
    Mar 14, 2013
    Posts:
    1,422
    Could you edit your post and repaste the code with proper formatting? It's just too difficult to read like it is.
     
    SkyTech6 likes this.
  3. SkyTech6

    SkyTech6

    Joined:
    Jul 14, 2015
    Posts:
    151
    As soon as I noticed I started editing it haha.
     
  4. larku

    larku

    Joined:
    Mar 14, 2013
    Posts:
    1,422
    Just cut and paste the code from the editor again - best not to edit anything.
     
    SkyTech6 likes this.
  5. SkyTech6

    SkyTech6

    Joined:
    Jul 14, 2015
    Posts:
    151
    Ah okay had to "Paste and Match Style" to get it to retain formatting. Sorry.
     
  6. larku

    larku

    Joined:
    Mar 14, 2013
    Posts:
    1,422
    Can you add this:

    Code (csharp):
    1.  
    2.     void Update () {
    3.         if (transform.position.y <= fallBoundary)
    4.         {
    5.             DamagePlayer (999999999);
    6.             Debug.Log("PLAYER DEAD - BOUNDARY FALL");
    7.         }
    8.  
    9.         if (playerStats.cur_Health <= 0) {
    10.             GameMaster.KillPlayer (this);
    11.             Debug.Log ("KILL PLAYER");
    12.         }
    13.  
    14.     }
    15.  
    Just to make sure that that isn't the cause.
     
    SkyTech6 likes this.
  7. SkyTech6

    SkyTech6

    Joined:
    Jul 14, 2015
    Posts:
    151
    I've inserted that and still continued to have the same problem. Added the debug console to OP thumbnails.
     
  8. larku

    larku

    Joined:
    Mar 14, 2013
    Posts:
    1,422
    What are those unassigned reference exceptions? You need to fix them first.

    It seems your health bar reference is not set properly in the inspector (the reference in this script). Make sure it's set correctly first.
     
    SkyTech6 likes this.
  9. SkyTech6

    SkyTech6

    Joined:
    Jul 14, 2015
    Posts:
    151
    Fixed that by turning Bar into a Prefab and using the Prefab as the GameObject via Inspector, but then when he dies or takes damage it doesn't affect the health bar at all.

    Screen Shot 2015-07-14 at 2.13.35 AM.png
     
  10. DWilliams

    DWilliams

    Joined:
    Jan 12, 2015
    Posts:
    63
    When your player dies, I assume the actual player object is destroyed and a new one is instantiated. If that's the case then the new instantiated player object won't have the reference to the health bar object that exists in your scene (you can probably see this in inspector after a respawn). You would have to make sure that each time you instantiate the player it finds the health bar and it should then be able to affect it again.

    Setting the reference to the prefab won't work because then you aren't changing anything about the object that exists in scene, you're only changing the prefab template.
     
    SkyTech6 likes this.
  11. SkyTech6

    SkyTech6

    Joined:
    Jul 14, 2015
    Posts:
    151
    Ah yea it does seem to have that problem... I can't quite figure out how to fix it though.

    When I have my player respawn I use this code in my GameMaster script

    Code (csharp):
    1.  
    2. public Transform playerPrefab;
    3.     public Transform spawnPoint;
    4.     public int spawnDelay = 2;
    5.  
    6.     public IEnumerator RespawnPlayer () {
    7.         yield return new WaitForSeconds (spawnDelay);
    8.  
    9.         Instantiate (playerPrefab, spawnPoint.position, spawnPoint.rotation);
    10.  
    So I'm guessing I'd need to make another Instantiate line that would recall the Health Bar's location in the Hierarchy... but I can't figure out how to do this....

    Also that still wouldn't fix the problem of the health bar simply going from full to empty even if it just takes 1 damage.
     
  12. DWilliams

    DWilliams

    Joined:
    Jan 12, 2015
    Posts:
    63
    After instantiating the new player you can find its Player script and use that to set the health bar reference.

    So have your GameMaster script hold the reference to the health bar that exists in the scene and after instantiating the new player, store the gameobject reference returned by the Instantiate call and use GetComponent<Player>() on that gameobject to get a reference to the newly instantiated player objects Player script and set the healthBar gameobject reference to the reference that GameMaster holds.

    So your GameMaster script:
    Code (CSharp):
    1.  
    2. public GameObject healthBar; //holds reference to scene health bar
    3.  
    4. ....
    5.  
    6. GameObject newplayer = Instantiate (playerPrefab, spawnPoint.position, spawnPoint.rotation) as GameObject;
    7. newplayer.GetComponent<Player>().healthBar = healthBar;
    8.  
    As for your other problem, I'm not sure. Seems like something is causing the Update on the player to get called before Start() sets your current health to full. You can add a debug to start and see when its called compared to the kill message from Update. Or maybe something else somewhere is changing the value of current health very quickly.
     
    SkyTech6 likes this.
  13. SkyTech6

    SkyTech6

    Joined:
    Jul 14, 2015
    Posts:
    151
    Okay guys! I got the health bar to work perfectly. Thanks immensely to larku and DWilliams, your help was vital in coming to this conclusion.

    I'm going to go ahead and post both of my scripts for anyone who comes onto this thread when searching for the same fix.

    GameMaster script

    Code (csharp):
    1.  
    2. using UnityEngine;
    3. using System.Collections;
    4.  
    5. public class GameMaster : MonoBehaviour {
    6.    
    7.     public GameObject healthBar;
    8.  
    9.     void Start () {
    10.    
    11.     }
    12.  
    13.     public Transform playerPrefab;
    14.     public Transform spawnPoint;
    15.     public int spawnDelay = 2;
    16.  
    17.     public IEnumerator RespawnPlayer () {
    18.         yield return new WaitForSeconds (spawnDelay);
    19.  
    20.         Instantiate (playerPrefab, spawnPoint.position, spawnPoint.rotation);
    21.         Debug.Log ("RESPAWN Player");
    22.     }
    23.  
    24.     public void KillPlayer (Player player) {
    25.         Destroy (player.gameObject);
    26.         StartCoroutine (RespawnPlayer());
    27.     }
    28.  
    29. }
    30.  
    Player script

    Code (csharp):
    1.  
    2.  
    3. public class Player : MonoBehaviour {
    4.  
    5.     [System.Serializable]
    6.     public class PlayerStats {
    7.  
    8.         public GameObject[] Ammo;
    9.     }
    10.  
    11.     public PlayerStats playerStats = new PlayerStats();
    12.     GameMaster gm;
    13.  
    14.     public int fallBoundary = -20;
    15.     public float max_Health = 100f;
    16.     public float cur_Health = 0f;
    17.     public GameObject healthBar;
    18.  
    19.  
    20.     void Start () {
    21.  
    22.         healthBar = GameObject.Find ("Bar");
    23.         gm = GameObject.FindObjectOfType<GameMaster>();
    24.         cur_Health = max_Health;
    25.         //InvokeRepeating ("decreasehealth",1f,1f); //Constant Damage Tester
    26.  
    27.  
    28.     }
    29.  
    30.     void Update () {
    31.         if (transform.position.y <= fallBoundary)
    32.         {
    33.             DamagePlayer (999999999);
    34.             Debug.Log("PLAYER DEAD - BOUNDARY FALL");
    35.         }
    36.        
    37.         if (cur_Health <= 0) {
    38.             gm.KillPlayer (this);
    39.             Debug.Log ("KILL PLAYER");
    40.         }
    41.  
    42.         float calc_Health = cur_Health / max_Health; // Raito Controller for Health Bar Progress
    43.         SetHealthBar (calc_Health);
    44.  
    45.     }
    46.  
    47.     public void DamagePlayer (int damage) {
    48.         cur_Health -= damage;
    49.  
    50.     }
    51.     //void decreasehealth(){
    52.         //cur_Health -= 10; // Constant Damage Tester
    53.  
    54.     //}
    55.  
    56.     public void SetHealthBar(float myHealth){
    57.    
    58.         healthBar.transform.localScale = new Vector3(Mathf.Clamp(myHealth,0,1), healthBar.transform.localScale.y, healthBar.transform.localScale.z);
    59.     }
    60. }
    61.  
    62.  
    Again major thanks to the both of you, and a few others who helped me out!

    I look forward to being a part of this community.