Unity 2D health bar

17,701

Solution 1

In your PlayerScript you retrieve the HealthScript with the following code:

HealthScript playerHealth = this.GetComponent<HealthScript>();

If you want to call methods on the Health script you would do something similar.

Health healthBar = this.GetComponent<Health>();
healthBar.modifyHealth(amountOfDamage);

This assumes all 3 scripts are on the same Game object.

Solution 2

With new UI system in Unity 4.6 it is really easy to create a health bar.

  • GameObject->UI->Image
  • Put your health bar sprite in image.
  • Change the Image type to Filled. Then you can play with Fill amount property and also control in through code
Share:
17,701

Related videos on Youtube

user3363310
Author by

user3363310

Updated on September 14, 2022

Comments

  • user3363310
    user3363310 over 1 year

    I am new to coding and Unity

    I have the health bar appearing on my screen, but I am not sure how to link the Health script of the health bar to my player script and my player's health script. Simply, I want to make it so when my player gets shot my health bar will lose a heart

    my health bar script

    using UnityEngine;
    using System.Collections;
    
    public class Health : MonoBehaviour {
    
        public int startHealth;
        public int healthPerHeart;
    
        private int maxHealth;
        private int currentHealth;
    
        public Texture[] heartImages;
        public GUITexture heartGUI;
    
        private ArrayList hearts = new ArrayList();
    
        // Spacing:
        public float maxHeartsOnRow;
        private float spacingX;
        private float spacingY;
    
    
        void Start () {
            spacingX = heartGUI.pixelInset.width;
            spacingY = -heartGUI.pixelInset.height;
    
            AddHearts(startHealth/healthPerHeart);
        }
    
        public void AddHearts(int n) {
            for (int i = 0; i <n; i ++) { 
                Transform newHeart = ((GameObject)Instantiate(heartGUI.gameObject,this.transform.position,Quaternion.identity)).transform; // Creates a new heart
                newHeart.parent = transform;
    
                int y = (int)(Mathf.FloorToInt(hearts.Count / maxHeartsOnRow));
                int x = (int)(hearts.Count - y * maxHeartsOnRow);
    
                newHeart.GetComponent<GUITexture>().pixelInset = new Rect(x * spacingX,y * spacingY,58,58);
                newHeart.GetComponent<GUITexture>().texture = heartImages[0];
                hearts.Add(newHeart);
    
            }
            maxHealth += n * healthPerHeart;
            currentHealth = maxHealth;
            UpdateHearts();
        }
    
    
        public void modifyHealth(int amount) {
            currentHealth += amount;
            currentHealth = Mathf.Clamp(currentHealth,0,maxHealth);
            UpdateHearts();
        }
    
        void UpdateHearts() {
            bool restAreEmpty = false;
            int i =0;
    
            foreach (Transform heart in hearts) {
    
                if (restAreEmpty) {
                    heart.guiTexture.texture = heartImages[0]; // heart is empty
                }
                else {
                    i += 1; // current iteration
                    if (currentHealth >= i * healthPerHeart) {
                        heart.guiTexture.texture = heartImages[heartImages.Length-1]; // health of current heart is full
                    }
                    else {
                        int currentHeartHealth = (int)(healthPerHeart - (healthPerHeart * i - currentHealth));
                        int healthPerImage = healthPerHeart / heartImages.Length; // how much health is there per image
                        int imageIndex = currentHeartHealth / healthPerImage;
    
    
                        if (imageIndex == 0 && currentHeartHealth > 0) {
                            imageIndex = 1;
                        }
    
                        heart.guiTexture.texture = heartImages[imageIndex];
                        restAreEmpty = true;
                    }
                }
    
            }
        }
    }
    

    my player script

    /// <summary>
    /// Player controller and behavior
    /// </summary>
    public class PlayerScript : MonoBehaviour
    {
        public Health health;
        /// <summary>
        /// 1 - The speed of the ship
        /// </summary>
        public Vector2 speed = new Vector2(50, 50);
    
        // 2 - Store the movement
        private Vector2 movement;
    
        void OnCollisionEnter2D(Collision2D collision)
        {
            bool damagePlayer = false;
    
            // Collision with enemy
            EnemyScript enemy = collision.gameObject.GetComponent<EnemyScript>();
            if (enemy != null)
            {
                // Kill the enemy
                HealthScript enemyHealth = enemy.GetComponent<HealthScript>();
                if (enemyHealth != null) enemyHealth.Damage(enemyHealth.hp);
    
                damagePlayer = true;
    
            }
    
            // Damage the player
            if (damagePlayer)
            {
                HealthScript playerHealth = this.GetComponent<HealthScript>();
                if (playerHealth != null) playerHealth.Damage(1);
    
            }
        }
    
    
    
        void Update()
        {
            // 3 - Retrieve axis information
            float inputX = Input.GetAxis("Horizontal");
            float inputY = Input.GetAxis("Vertical");
    
            // 4 - Movement per direction
            movement = new Vector2(
                speed.x * inputX,
                speed.y * inputY);
    
            // 5 - Shooting
            bool shoot = Input.GetButtonDown("Fire1");
            shoot |= Input.GetButtonDown("Fire2");
            // Careful: For Mac users, ctrl + arrow is a bad idea
    
            if (shoot)
            {
                WeaponScript weapon = GetComponent<WeaponScript>();
                if (weapon != null)
                {
                    // false because the player is not an enemy
                    weapon.Attack(false);
                }
            }
            // 6 - Make sure we are not outside the camera bounds
            var dist = (transform.position - Camera.main.transform.position).z;
    
            var leftBorder = Camera.main.ViewportToWorldPoint(
                new Vector3(0, 0, dist)
                ).x;
    
            var rightBorder = Camera.main.ViewportToWorldPoint(
                new Vector3(1, 0, dist)
                ).x;
    
            var topBorder = Camera.main.ViewportToWorldPoint(
                new Vector3(0, 0, dist)
                ).y;
    
            var bottomBorder = Camera.main.ViewportToWorldPoint(
                new Vector3(0, 1, dist)
                ).y;
    
            transform.position = new Vector3(
                Mathf.Clamp(transform.position.x, leftBorder, rightBorder),
                Mathf.Clamp(transform.position.y, topBorder, bottomBorder),
                transform.position.z
                );
    
        }
    
        void FixedUpdate()
        {
            // 5 - Move the game object
            rigidbody2D.velocity = movement;
        }
    
        void OnDestroy() 
        {
            Application.LoadLevel("gameOver"); 
        } 
    
    }
    

    and my player's health script

    using UnityEngine;
    
    /// <summary>
    /// Handle hitpoints and damages
    /// </summary>
    public class HealthScript : MonoBehaviour
    {   
        /// <summary>
        /// Total hitpoints
        /// </summary>
        public int hp = 1;
    
        /// <summary>
        /// Enemy or player?
        /// </summary>
        public bool isEnemy = true;
    
        /// <summary>
        /// Inflicts damage and check if the object should be destroyed
        /// </summary>
        /// <param name="damageCount"></param>
        public void Damage(int damageCount)
        {
            hp -= damageCount;
    
            if (hp <= 0)
            {
                // 'Splosion!
                SpecialEffectsHelper.Instance.Explosion(transform.position);
    
                // Dead!
                Destroy(gameObject);
            }
        }
    
        void OnTriggerEnter2D(Collider2D otherCollider)
        {
            // Is this a shot?
            ShotScript shot = otherCollider.gameObject.GetComponent<ShotScript>();
            if (shot != null)
            {
                // Avoid friendly fire
                if (shot.isEnemyShot != isEnemy)
                {
                    Damage(shot.damage);
    
                    // Destroy the shot
                    Destroy(shot.gameObject); // Remember to always target the game object, otherwise you will just remove the script
                }
            }
        }
    }