Home Unity

HealthBar below zero

Greg DAlessandro
polycounter lvl 6
Offline / Send Message
Greg DAlessandro polycounter lvl 6
Does anyone know how to make the healthbar stop at zero? (it currently goes below zero) Thank you.
using UnityEngine;
using System.Collections;
using UnityEngine.UI;

public class HealthBar : MonoBehaviour
{
	#region FIELDS
	
	// The player's current health
	public int currentHealth;
	
	// The player's max health
	public int maxHealth;
	
	// The health bar's speed
	public float healthSpeed;
	
	// The health text
	public Text healthText;
	
	// The health's image, this is used for color changing
	public Image visualHealth;
	
	// The current xValue of the health
	private float currentValue;
	
	// How often can I take damage
	public float cooldown;
	
	// Indicates if we can take damage or not
	private bool onCD;
	
	// The healthbar's canvas
	public Canvas canvas;
	
	#endregion
	
	#region PROPERTIES
	
	// Property for accessing the player's health
	public int Health
	{
		get
		{ 
			return currentHealth;
		}
		set
		{
			currentHealth = value;
		}
	}        
	
	#endregion
	
	// Use this for initialization
	void Start()
	{
		// Sets all start values
		onCD = false;
		
		//Sets the current health to the maxHealth
			currentHealth = maxHealth;    
	}
	
	// Update is called once per frame
	void Update()
	{
		HandleHealthbar();
		if (Input.GetKeyDown(KeyCode.Space))
		{
			Health -= 10;
		}
	}
	
	// Handles the healthbar my moving it and changing color
	private void HandleHealthbar()
	{
		// Writes the current health in the text field
		healthText.text = "Health: " + currentHealth;
		
		// Maps the min and max position to the range between 0 and max health
		currentValue = Map( currentHealth, 0, maxHealth, 0, 1);
		
		// Sets the fillAmount of the health to simulate reduction of health 
		visualHealth.fillAmount = Mathf.Lerp( visualHealth.fillAmount, currentValue, Time.deltaTime * healthSpeed );
		
		// If we have more than 50% health we use the green colors
		if ( currentHealth > maxHealth /2 )
		{
			visualHealth.color = new Color32( ( byte ) Map( currentHealth, maxHealth / 2, maxHealth, 255, 0 ), 255, 0, 255 );
		}
		// If we have less than 50% health we use the red colors
		else 
		{
			visualHealth.color = new Color32( 255, ( byte ) Map ( currentHealth, 0, maxHealth / 2, 0, 255 ), 0, 255); 
		}
	}
	
	void OnTriggerStay( Collider other )
	{
		// Used for simulating taking damage
		if ( other.tag == "Damage" )
		{
			if ( !onCD && currentHealth > 1 )
			{
				// Makes sure that we can't take damage right away
				StartCoroutine ( CoolDownDmg() );
				// Uses the Health Property so that we recolor and rescale the health when we change it
				Health -= 1;
			}
		}
		
		// Used for simulating gaining health
		if ( other.tag == "Health" )
		{
			if ( !onCD && currentHealth < maxHealth )
			{
				// Makes sure that we can't take damage right away
				StartCoroutine( CoolDownDmg() );
				// Uses the Health Property so that we can recolor and rescale the health when we change it
				Health += 1;
			}
		}
	}
	
	// Keeps track of the damage CD
	IEnumerator CoolDownDmg()
	{
		onCD = true;
		// Waits a while before we are able to take damage again
		yield return new WaitForSeconds( cooldown );
		onCD = false;
	}
	
	// This method maps a range of numbers into another range
	// <param name="x">The value to evaluate</param>
	// <param name="in_min">The minimum value of the evaluated variable</param>
	// <param name="in_max">The maximum value of the evaluated variable</param>
	// <param name="out_min">The minimum number we want to map to</param>
	// <param name="out_max">The maximum number we want to map to</param>
	// <returns></returns>
	public float Map(float x, float in_min, float in_max, float out_min, float out_max)
	{
		return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
	}
	
	
}

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 6
    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.
    void Update()
        {
            HandleHealthbar();
            if (Input.GetKeyDown(KeyCode.Space))
            {
                Health -= 10;
            }
            if (Health <= 0)
            {
                Health = 0;
            }
            if (Health >= maxHealth)
            {
                Health = maxHealth;
            }
        }
    

    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 6
    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:
    // Sets the fillAmount of the health to simulate reduction of health 
    if currentHealth !=0 ()
    {
    visualHealth.fillAmount = Mathf.Lerp( visualHealth.fillAmount, currentValue, Time.deltaTime * healthSpeed );
    }
    

    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
    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.