Author Topic: So you want to make health bars...  (Read 61702 times)

ArenMook

  • Administrator
  • Hero Member
  • *****
  • Thank You
  • -Given: 337
  • -Receive: 1171
  • Posts: 22,128
  • Toronto, Canada
    • View Profile
So you want to make health bars...
« on: April 20, 2012, 10:04:01 PM »
Since I get a question about this roughly once a day...

Video: http://www.youtube.com/watch?v=idVr8-jfdAI

Code: (below... scroll down)
« Last Edit: February 26, 2013, 07:16:30 AM by ArenMook »

Sarus

  • Guest
Re: So you want to make health bars...
« Reply #1 on: May 13, 2012, 04:46:40 AM »
Hi Aren,

If we wanted the health bars to get larger and smaller as you move closer and further away from the GameObject they are floating over (in this case the coins), what changes would be required?  Is there a way to get this effect with a 2d UI (have the bars scale based on distance from a GameObject), or do we need to use a 3d UI?

Thanks!  Also, thank you for providing the example project found in that thread.  Very useful.

~Ed

ArenMook

  • Administrator
  • Hero Member
  • *****
  • Thank You
  • -Given: 337
  • -Receive: 1171
  • Posts: 22,128
  • Toronto, Canada
    • View Profile
Re: So you want to make health bars...
« Reply #2 on: May 13, 2012, 06:23:01 AM »
Keeping them in 2D and adjusting their Z as well as scaling them is generally easier as then you can also make sure that they stay relatively proper (not too small or not too big).

Sarus

  • Guest
Re: So you want to make health bars...
« Reply #3 on: May 15, 2012, 08:27:48 PM »
If we go with the method of scaling a 2d UI element based on distance from the game camera there's no way to do depth testing with in game objects right?

ArenMook

  • Administrator
  • Hero Member
  • *****
  • Thank You
  • -Given: 337
  • -Receive: 1171
  • Posts: 22,128
  • Toronto, Canada
    • View Profile
Re: So you want to make health bars...
« Reply #4 on: May 15, 2012, 09:26:34 PM »
Nope, for that you need to keep your widgets in 3D.

tinyutopia

  • Newbie
  • *
  • Thank You
  • -Given: 0
  • -Receive: 0
  • Posts: 15
    • View Profile
Re: So you want to make health bars...
« Reply #5 on: June 21, 2012, 04:47:09 PM »
I'm scaling my health bar sliders with this this code:

  1.         public void UpdateDisplay( float x) {
  2.                 if( x < 0 )
  3.                         x = 0;
  4.                 else if( x > 1 )
  5.                         x = 1;
  6.                        
  7.                 _slider.foreground.localScale = new Vector3( _maxWidth * x, _slider.foreground.localScale.y, _slider.foreground.localScale.z );
  8.                 oldxp = GameManager.Instance.curxp;
  9.         }

The problem is that whenever x = 0, when I view the health bar on my build, it distorts stretching the sprite across the screen where it terminates somewhere in the center of the game view. Not sure why this is happening, maybe I just need to disable this sprite if x = 0. Is there a better way?

ArenMook

  • Administrator
  • Hero Member
  • *****
  • Thank You
  • -Given: 337
  • -Receive: 1171
  • Posts: 22,128
  • Toronto, Canada
    • View Profile
Re: So you want to make health bars...
« Reply #6 on: June 21, 2012, 05:19:27 PM »
Don't scale the sprite. Scale the parent game object. I also suggest scaling uniformly -- that is scale X, Y, and Z by an equal amount. Lastly, if X is 0, then your scale becomes 0. That's invalid to begin with. I suggest adding min/max.

Bantis

  • Guest
Re: So you want to make health bars...
« Reply #7 on: August 20, 2012, 07:33:54 PM »
Any chance of this getting reposted? The link just takes you to the front page of the site.

ArenMook

  • Administrator
  • Hero Member
  • *****
  • Thank You
  • -Given: 337
  • -Receive: 1171
  • Posts: 22,128
  • Toronto, Canada
    • View Profile
Re: So you want to make health bars...
« Reply #8 on: August 20, 2012, 08:20:17 PM »
I had to take down the old forum as it had a security hole in it, which is why that page no longer exists. I'll see if I can find the code for it later, although HUDText extension does the whole "UI component following a 3D object" thing pretty well. Slap a slider on there, and you've got a health bar above the unit's head.

gamesonytablet

  • Newbie
  • *
  • Thank You
  • -Given: 0
  • -Receive: 0
  • Posts: 13
    • View Profile
Re: So you want to make health bars...
« Reply #9 on: September 05, 2012, 07:50:48 AM »
Hi, still looking for the original code? Even though the HUDText approach is interesting as well, I have a blog post that introduced this functionality in Japanese, and my access log tells me there are people looking for how to implement this literally every day.
I'm assuming there are others looking for this as well. (like me!   :'()

ArenMook

  • Administrator
  • Hero Member
  • *****
  • Thank You
  • -Given: 337
  • -Receive: 1171
  • Posts: 22,128
  • Toronto, Canada
    • View Profile
Re: So you want to make health bars...
« Reply #10 on: September 05, 2012, 03:35:15 PM »
This goes on the 3D game object, and should reference a prefab you've created for the Unit's HUD object that has a UnitHUD script on it:
  1. using UnityEngine;
  2.  
  3. /// <summary>
  4. /// Example script that instantiates a HUD window that will follow this game object.
  5. /// </summary>
  6.  
  7. [AddComponentMenu("NGUI/Examples/Add Unit HUD")]
  8. public class AddUnitHUD : MonoBehaviour
  9. {
  10.         public GameObject prefab;
  11.  
  12.         void Start ()
  13.         {
  14.                 if (prefab != null)
  15.                 {
  16.                         UICamera cam = UICamera.FindCameraForLayer(prefab.layer);
  17.  
  18.                         if (cam != null)
  19.                         {
  20.                                 GameObject go = cam.gameObject;
  21.                                 UIAnchor anchor = go.GetComponent<UIAnchor>();
  22.                                 if (anchor != null) go = anchor.gameObject;
  23.  
  24.                                 GameObject child = GameObject.Instantiate(prefab) as GameObject;
  25.                                 Transform t = child.transform;
  26.                                 t.parent = go.transform;
  27.                                 t.localPosition = Vector3.zero;
  28.                                 t.localRotation = Quaternion.identity;
  29.                                 t.localScale = Vector3.one;
  30.  
  31.                                 UnitHUD hud = child.GetComponent<UnitHUD>();
  32.                                 if (hud != null) hud.target = transform;
  33.                         }
  34.                         else
  35.                         {
  36.                                 Debug.LogWarning("No camera found for layer " + LayerMask.LayerToName(prefab.layer), gameObject);
  37.                         }
  38.                 }
  39.                 Destroy(this);
  40.         }
  41. }
This goes on the HUD object -- a UI prefab that you want to follow your unit. This is where you'll place such things as health bars, unit name, etc.
  1. using UnityEngine;
  2.  
  3. /// <summary>
  4. /// Example script showing how to add UI window that follows an object drawn by another camera.
  5. /// </summary>
  6.  
  7. [AddComponentMenu("NGUI/Examples/Unit HUD")]
  8. public class UnitHUD : MonoBehaviour
  9. {
  10.         /// <summary>
  11.         /// Target object this UI element should follow.
  12.         /// </summary>
  13.  
  14.         public Transform target;
  15.  
  16.         Transform mTrans;
  17.         Camera mGameCam;
  18.         Camera mUICam;
  19.         Vector3 mPos;
  20.         bool mVisible = true;
  21.  
  22.         void Start ()
  23.         {
  24.                 if (target == null) { Destroy(gameObject); return; }
  25.                 mTrans = transform;
  26.                 mGameCam = NGUITools.FindCameraForLayer(target.gameObject.layer);
  27.                 mUICam = NGUITools.FindCameraForLayer(gameObject.layer);
  28.         }
  29.  
  30.         void LateUpdate()
  31.         {
  32.                 if (target == null) { Destroy(gameObject); return; }
  33.  
  34.                 mPos = mGameCam.WorldToViewportPoint(target.position);
  35.  
  36.                 bool visible = (mPos.z > 0f && mPos.x > 0f && mPos.x < 1f && mPos.y > 0f && mPos.y < 1f);
  37.  
  38.                 if (mVisible != visible)
  39.                 {
  40.                         mVisible = visible;
  41.                         UIWidget[] widgets = gameObject.GetComponentsInChildren<UIWidget>();
  42.                         foreach (UIWidget w in widgets) w.enabled = mVisible;
  43.                 }
  44.                
  45.                 if (mVisible)
  46.                 {
  47.                         mPos = mUICam.ViewportToWorldPoint(mPos);
  48.                         mPos.z = 0f;
  49.                         mTrans.position = mPos;
  50.                 }
  51.         }
  52. }

gamesonytablet

  • Newbie
  • *
  • Thank You
  • -Given: 0
  • -Receive: 0
  • Posts: 13
    • View Profile
Re: So you want to make health bars...
« Reply #11 on: September 05, 2012, 07:36:07 PM »
Thanks for your quick action! ;)

SketchWork

  • Newbie
  • *
  • Thank You
  • -Given: 1
  • -Receive: 0
  • Posts: 44
    • View Profile
Re: So you want to make health bars...
« Reply #12 on: September 07, 2012, 02:33:24 PM »
The link on your first post no longer works for some reason.

ArenMook

  • Administrator
  • Hero Member
  • *****
  • Thank You
  • -Given: 337
  • -Receive: 1171
  • Posts: 22,128
  • Toronto, Canada
    • View Profile
Re: So you want to make health bars...
« Reply #13 on: September 07, 2012, 03:49:36 PM »
Yup, I reposted the code later in the thread.

capitalj

  • Jr. Member
  • **
  • Thank You
  • -Given: 5
  • -Receive: 0
  • Posts: 88
    • View Profile
Re: So you want to make health bars...
« Reply #14 on: September 28, 2012, 05:20:50 PM »
How would I adjust this code to make a health bar or HUD item that uses a 3D NGUI camera? I tried the same code but the HUD object is just positioned at the same world position as the targetTransform (meaning that it is no longer visible by the 3D NGUI camera).