1
\$\begingroup\$

I would like to create a small health bar on top of each enemy in my game. I know how to do this for one enemy, but I'm not completely sure how best to expand it to work for each enemy in the game. I'm guessing I should instantiate the UI health bar prefab somewhere, each time an enemy is spawned maybe? Currently, I don't even have an enemy spawner, I'm just testing by dragging enemy prefabs into the scene. I'll post the relevant scripts.

public class EnemyHealthBarController : MonoBehaviour 
{
    private Image remainingHealthImage;

    private EnemyHealth enemyHealth;

    void Start()
    {
        remainingHealthImage = transform.Find("Remaining Health Image").gameObject.GetComponent<Image>();

        enemyHealth = GameObject.FindGameObjectWithTag("Enemy").GetComponent<EnemyHealth>();
    }

    void Update()
    {
        remainingHealthImage.fillAmount = enemyHealth.currentHealth / enemyHealth.maxHealth;

        if (enemyHealth.isDead)
        {
            gameObject.SetActive(false);
        }
    }
}

and

public class ClampEnemyHealthBar : MonoBehaviour 
{
    private GameObject enemyHealthBar;

    private Vector3 offset;

    void Start()
    {
        enemyHealthBar = GameObject.Find("Enemy Health Bar");

        offset = new Vector3(0f, 30f, 0f);
    }

    void LateUpdate()
    {
        Vector3 desiredPosition = Camera.main.WorldToScreenPoint(transform.position) + offset;
        enemyHealthBar.transform.position = desiredPosition;
    }
}

Right now, I'm using GameObject.Find to set a reference to the preexisting enemy health bar in the scene. Also, I'm only finding the EnemyHealth component of one of the enemies. How might I better structure this in order to do the kind of thing I'm trying to do?

\$\endgroup\$
  • 1
    \$\begingroup\$ The flaw here is in enemyHealthBar = GameObject.Find("Enemy Health Bar"); as it assumes there is exactly 1 health bar in the scene. GameObject.FindGameObjectWithTag("Enemy") is similarly flawed. You need to hold references to your enemies when you create them and pass this reference to the health bar when you create it. \$\endgroup\$ – Draco18s May 28 '17 at 2:44
2
\$\begingroup\$

Make your health bar a child object of your enemy object. Then either just use transform.parent.gameObject to get to the parent object, or just reference your game object in the health bar's script by using public GameObject parentObject; and then dragging the parent object in there.

This way, you won't have to think about setting each and every health bar to the correct object, because the objects will already have health bars.

At least this is how I would do it. There are tutorials on how to use World Space UI objects and how to do parent-child relationships and prefabs online, check those out if you want to learn more.

\$\endgroup\$
  • 1
    \$\begingroup\$ Thank you very much! I'm pretty new to game development and hadn't realized that I could make my canvas a child of a game object. \$\endgroup\$ – embracethefuture May 29 '17 at 0:54

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.