Help With Enemy Health bars

Ok. So here is my problem:
I am trying to make enemy healthbars for my enemies. This shouldn’t be too hard to just add a guitexture above individual enemies and display their healthbars on it, however, my enemies are all instantiated and so i can’t find a way to overcome the problem of each instantiated enemy having its own health bar.

I have looked at the following link “ObjectLabel.js”
and despite the fact that the code is supposed to be used for gui texts rather than an image, my final code will probably be similar to it. Something important I know is that im going to need to use an ONGUI(){} function somewhere, because Unity doesn’t allow you to make any GUI texture or text as a child of a prefab in the inspector.

To make it simpler for anyone wanting to help me with coding this, I am not going to clamp the enemies’ healthbars to the screen (They won’t be visible once an enemy leaves the screen).

It would also be cool if I could know whether or not the healthbars for the enemy needs to be attached to the enemy prefab or to the script which instantiates them (or even a bit in both!).

AND ALSO!!!, Is there any other approach that would save processing or is this the fastest method; because in the final stages of the game there may be up to 30 enemies on the screen at once.

Thanks in advance = )

Below is a minimally altered version of Professor Snake’s code, converted to c#, with an added section that “uncenters” the health bar and makes it appear to negate from the right hand side (a traditional floating health bar). It works perfectly in my project, so I hope it helps out!

using UnityEngine;
using System.Collections;

/// <summary>
/// 
/// Created by A.Roberts, June 9, 2013
/// 
/// Attach to empty gameObject that is parent to both the green
/// and red planes. Drag green bar into the "greenBar" public
/// field.
/// 
/// </summary>

public class EnemyHealthBar_Green: MonoBehaviour {
	
		public float initialGreenLength;
		public GameObject greenBar;
		public float curHealth;
		public float maxHealth;
	
		public float lastHealth;
	
		Vector3 greenPos;
	
		EnemyHealth healthScript;
		
		public float timer;
		float time = 2;
		
	void Awake ()
		{
		
		//loads enemy health value from healthScript
		healthScript = transform.parent.gameObject.GetComponent<EnemyHealth>();
		curHealth = healthScript.curHealth;
		maxHealth = healthScript.maxHealth;
		
		//stores two health values, will come in later
		lastHealth = curHealth;
		}
	
	
	void Update () 
		{

		timer -= Time.deltaTime;

	
		if(timer <= 0)
			{
			timer = 0.05f;
			
		// adjusts the greenHealthBar so that as the enemy takes damage
		// the bar shifts to the left, making it appear that the damage
		// is coming off the right side of the bar and not equally from
		// each end.
			
			if(lastHealth > curHealth)
				{
				greenPos = greenBar.transform.localPosition;
				greenPos.x = (lastHealth - curHealth)/curHealth;
				greenBar.transform.localPosition = greenPos;
				lastHealth = curHealth;
				}
			}
				
		curHealth = healthScript.curHealth;
		maxHealth = healthScript.maxHealth;
		
		// C# conversion of Professor Snake's awesome code from Unity forum's
		// http://answers.unity3d.com/questions/403008/help-with-enemy-health-bars.html
		
		Vector3 greenScale = greenBar.transform.localScale;
		greenScale.x = 2 * (curHealth/maxHealth);
		greenScale.y = greenScale.y;
		transform.localScale = greenScale;
				
 		//keeps bar facing camera
		transform.LookAt(Camera.main.transform);
		
	}
}

Using OnGUI would not be advised for such a task. Instead, have two planes, a red and a green one, that represent each enemy’s life bar. Have them be a child of an empty gameobject and attach that to the enemy’s prefab. Then you can modify the green plane’s x size based on the enemies’ health. For instance:

var initialGreenLength:float;
var greenBar:GameObject;
var health:float=100;
var maxHealth:float=100;

function Awake(){
health=maxHealth;
initialGreenLength=.greenBar.transform.localScale.x;
}

function Update(){
greenBar.transform.localScale.x=initialGreenLength*(health/maxHealth);

}

In order to have the planes always face the camera, you can use this simple piece of code somewhere:

transform.rotation=camera.main.transform.rotation;

In order to make it simple, have the above code edit the rotation of the parent empty gameobject of the two bars.
This is what the two bars should look like after some damage has been applied (Yes, cubes work equally as well):
alt text
You can also use another line to move the green cube to the side, in order to have a more traditional life bar. I am experimenting with the values it needs at the moment, i’ll post the code for that once i properly figure it out.
Make sure to avoid Z-Fighting on the front by placing them properly.

I’m using the following to hang the enemy health bar (GUI Texture) on an empty game object attached to the enemy:

public class GUI_Placement : MonoBehaviour 
{
	public Transform target; //The target is set as the empty object attached to the enemy from the inspector
	
	void Update () 
	{
		transform.position = Camera.main.WorldToViewportPoint(target.position);
		//transform.rotation = Camera.main.transform.rotation; //
	}
}

This works well in placing the GUI Texture (health bar) in the vicinity of the enemy. But there’s a problem I’m trying to resolve. This is a top down game where the enemy moves in 2 dimensions. As the enemy starts the move around, the health bar stays at a fixed point relative to the enemy but will also rotate around so that the bar is always horizontal with the screen. What I want is the bar to keep the same orientation that the enemy has. The enemy is a vehicle so I want the bar to stay perpendicular to the enemy’s local forward vector at all times. Any advice on how to do this will be great.