Health bar above enemy

Been trying to make a health bar follow the enemy, but can’t get it to work. Here is my current code:

public class HealthBar : MonoBehaviour {
    GameObject EnemyHealth, clone;
    public Transform target;


    // Use this for initialization
    void Start () {
        clone = Instantiate(EnemyHealth);
        clone.transform.SetParent(GameObject.Find("Canvas").transform, false);
    }

    private void Awake() {
        EnemyHealth = GameObject.Find("HealthBAR");
        target = gameObject.transform;
    }

    // Update is called once per frame
    void Update () {
        clone.transform.position  = Camera.main.WorldToScreenPoint(target.position);
    }
}

I attach the script to the enemy that I want to have a health bar but the position of the health bar doesn’t update. Any idea what’s wrong with the code? I don’t get any errors.

make the health bar gameobject a child of the player or enemy gameobject.
is the gameobject “Canvas” a child of the player or enemy?

EnemyGameObject/Canvas/healthbar

I have a Canvas UI and I just make the health bar(which is just an image) a child of the canvas, because I read that if you make too many canvas’s at a time it effects the preformence drastically. That’s why I would have all the health bars be children of a single canvas

GameObject.Find may be your issue. I find it usually is. (And even if it’s not the problem in this case, you shouldn’t use it)

What is the “HealthBAR” object? Is it just a thing that exists to be cloned? If so, it should probably be made into a prefab and put into the Resources folder instead.

Ok created a prefab of the health bar and changed the GameObject.Find. Still position not updating.

public class HealthBar : MonoBehaviour {
    public GameObject EnemyHealthBar;
    Transform target;
    GameObject EnemyHealth;



    // Use this for initialization
    void Start () {
        EnemyHealth = Instantiate(EnemyHealthBar);
        EnemyHealth.transform.SetParent(GameObject.FindGameObjectWithTag("Canvas").transform, false);
    }

    private void Awake() {
        target = gameObject.transform;
    }

    // Update is called once per frame
    void Update () {
        EnemyHealth.transform.position  = Camera.main.WorldToScreenPoint(target.position);
    }
}

Create two Debug.Log statements:

Debug.Log("EnemyHealth", EnemyHealth);
Debug.Log("Canvas", GameObject.FindGameObjectWithTag("Canvas"));

Put them somewhere (in Start() is probably fine) and run the game. When you click on them, make sure that they highlight the expected objects.

Everyting looks fine, here are some photos maybe that will help

https://gyazo.com/e7d09173bcb4ab22eeb82d41be6e4d1f
https://gyazo.com/2002b8752670d2b66c7e5d9b6c9fba51
https://gyazo.com/2bd628d3948e01dbac610ecc5e312bb5
https://gyazo.com/e6ba44c8685557a40c87f6bd73521889
https://gyazo.com/79f33157f7f2ddc144bb24f101e40fc8

The white bar is the health bar, it just sits there after I instantiate it at the start of the game.

Ok, I know where the problem is, but no idea why is it happening. The update function is never called, I just put a Debug.Log in the update function and it never appears in the console. Any idea why is this happening?

EDIT: It seems the problem is EnemyHealth.transform.position = Camera.main.WorldToScreenPoint(target.position); , because when I comment it out or I put Debug.Log above it the Debug.Log works properly.

Ok, I feel stupid and disappointed now… It didn’t work because I didn’t tag my camera to “MainCamera”. And I spent like a good 2 hours on this “bug”…

it happens… to the best of us.

Why not make the health bar a child of the enemy at spawn, then just drag the health bar into the public gameobject in the inspector to assign it. (On the enemy prefab that is!)

Secondly, you could set the canvas to “world space” to ensure that it follows your enemy in the position it was set. Would probably save a tiny amount of CPU time as it would negate the position updates in the script above completely and instead use Unity’s native system.

2 Likes