Home Unity

HealthBar below zero

Greg DAlessandro
polycounter lvl 11
Offline / Send Message
Greg DAlessandro polycounter lvl 11
Does anyone know how to make the healthbar stop at zero? (it currently goes below zero) Thank you.
  1. using UnityEngine;
  2. using System.Collections;
  3. using UnityEngine.UI;
  4.  
  5. public class HealthBar : MonoBehaviour
  6. {
  7. #region FIELDS
  8. // The player's current health
  9. public int currentHealth;
  10. // The player's max health
  11. public int maxHealth;
  12. // The health bar's speed
  13. public float healthSpeed;
  14. // The health text
  15. public Text healthText;
  16. // The health's image, this is used for color changing
  17. public Image visualHealth;
  18. // The current xValue of the health
  19. private float currentValue;
  20. // How often can I take damage
  21. public float cooldown;
  22. // Indicates if we can take damage or not
  23. private bool onCD;
  24. // The healthbar's canvas
  25. public Canvas canvas;
  26. #endregion
  27. #region PROPERTIES
  28. // Property for accessing the player's health
  29. public int Health
  30. {
  31. get
  32. {
  33. return currentHealth;
  34. }
  35. set
  36. {
  37. currentHealth = value;
  38. }
  39. }
  40. #endregion
  41. // Use this for initialization
  42. void Start()
  43. {
  44. // Sets all start values
  45. onCD = false;
  46. //Sets the current health to the maxHealth
  47. currentHealth = maxHealth;
  48. }
  49. // Update is called once per frame
  50. void Update()
  51. {
  52. HandleHealthbar();
  53. if (Input.GetKeyDown(KeyCode.Space))
  54. {
  55. Health -= 10;
  56. }
  57. }
  58. // Handles the healthbar my moving it and changing color
  59. private void HandleHealthbar()
  60. {
  61. // Writes the current health in the text field
  62. healthText.text = "Health: " + currentHealth;
  63. // Maps the min and max position to the range between 0 and max health
  64. currentValue = Map( currentHealth, 0, maxHealth, 0, 1);
  65. // Sets the fillAmount of the health to simulate reduction of health
  66. visualHealth.fillAmount = Mathf.Lerp( visualHealth.fillAmount, currentValue, Time.deltaTime * healthSpeed );
  67. // If we have more than 50% health we use the green colors
  68. if ( currentHealth > maxHealth /2 )
  69. {
  70. visualHealth.color = new Color32( ( byte ) Map( currentHealth, maxHealth / 2, maxHealth, 255, 0 ), 255, 0, 255 );
  71. }
  72. // If we have less than 50% health we use the red colors
  73. else
  74. {
  75. visualHealth.color = new Color32( 255, ( byte ) Map ( currentHealth, 0, maxHealth / 2, 0, 255 ), 0, 255);
  76. }
  77. }
  78. void OnTriggerStay( Collider other )
  79. {
  80. // Used for simulating taking damage
  81. if ( other.tag == "Damage" )
  82. {
  83. if ( !onCD && currentHealth > 1 )
  84. {
  85. // Makes sure that we can't take damage right away
  86. StartCoroutine ( CoolDownDmg() );
  87. // Uses the Health Property so that we recolor and rescale the health when we change it
  88. Health -= 1;
  89. }
  90. }
  91. // Used for simulating gaining health
  92. if ( other.tag == "Health" )
  93. {
  94. if ( !onCD && currentHealth < maxHealth )
  95. {
  96. // Makes sure that we can't take damage right away
  97. StartCoroutine( CoolDownDmg() );
  98. // Uses the Health Property so that we can recolor and rescale the health when we change it
  99. Health += 1;
  100. }
  101. }
  102. }
  103. // Keeps track of the damage CD
  104. IEnumerator CoolDownDmg()
  105. {
  106. onCD = true;
  107. // Waits a while before we are able to take damage again
  108. yield return new WaitForSeconds( cooldown );
  109. onCD = false;
  110. }
  111. // This method maps a range of numbers into another range
  112. // <param name="x">The value to evaluate</param>
  113. // <param name="in_min">The minimum value of the evaluated variable</param>
  114. // <param name="in_max">The maximum value of the evaluated variable</param>
  115. // <param name="out_min">The minimum number we want to map to</param>
  116. // <param name="out_max">The maximum number we want to map to</param>
  117. // <returns></returns>
  118. public float Map(float x, float in_min, float in_max, float out_min, float out_max)
  119. {
  120. return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
  121. }
  122. }

heaalQ_zpsfd6fxqia.jpg

Replies

  • NegevPro
    Offline / Send Message
    NegevPro polycounter lvl 4
    You just need to add a check in the Update function that checks to see if the current health is less than 0, if it is then set the health to 0. You should also add a check to see if the current health is greater than the max health, and set it to the max health if it is.
  • Greg DAlessandro
    Offline / Send Message
    Greg DAlessandro polycounter lvl 11
    I did add an If current health >= 0 in Update(), but if I take multiple hits before it reaches zero it still goes to negative hp.
  • NegevPro
    Offline / Send Message
    NegevPro polycounter lvl 4
    Are you sure you put the statement in the right method? I just tested it by copying your script into a new project and adding zero/max checks in the update function and it seems to be working fine.
    1. void Update()
    2. {
    3. HandleHealthbar();
    4. if (Input.GetKeyDown(KeyCode.Space))
    5. {
    6. Health -= 10;
    7. }
    8. if (Health <= 0)
    9. {
    10. Health = 0;
    11. }
    12. if (Health >= maxHealth)
    13. {
    14. Health = maxHealth;
    15. }
    16. }

    If that doesn't work, then it is possible there could be another active script in your scene that is conflicting with this script, although it's unlikely since I'd imagine you would know about it.
  • Greg DAlessandro
    Offline / Send Message
    Greg DAlessandro polycounter lvl 11
    The health now stops going negative, but there is still one issue:

    once the currentHealth = 0, the fill keeps cycling (is there a way to stop the fill from continuously going down?)


    I tried this:
    1. // Sets the fillAmount of the health to simulate reduction of health
    2. if currentHealth !=0 ()
    3. {
    4. visualHealth.fillAmount = Mathf.Lerp( visualHealth.fillAmount, currentValue, Time.deltaTime * healthSpeed );
    5. }

    The issue is once current health = 0 the fill amount stops in its tracks
    (ie. does not reach 0 fill since it is going down over time)
    Anyone know how to fix this?

    deadFill_zpsi0cxmzb4.jpg
  • Farfarer
    Offline / Send Message
    Farfarer polycounter lvl 17
    You'll need to do the check another way that isn't reliant on the actual health value (or simply discard the check).
  • Zephiris
    Offline / Send Message
    Zephiris polygon
    I think you might be looking for the clamp function, it lets you specifiy a min/max value, and if your variable is outside of that range when you use the function, it gets cut off to the min or max value. Saves you some lines of code, too :)

    http://docs.unity3d.com/ScriptReference/Mathf.Clamp.html
Sign In or Register to comment.