Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Floating health bar above Enemy

Discussion in 'Scripting' started by moynzy, Nov 19, 2014.

  1. moynzy

    moynzy

    Joined:
    Oct 22, 2014
    Posts:
    82
    Hey guys, on 3D unity I am trying to create a floating health bar that sits above the enemy.

    From searching the electric ocean I've been pointed to "WorldToScreenPoint", and from the document got this code.
    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4. public class enemyHealthBar : MonoBehaviour {
    5.  
    6.     public Transform target;
    7.  
    8.     // Use this for initialization
    9.     void Start () {
    10.  
    11.     }
    12.    
    13.  
    14.     void Update() {
    15.         Vector3 screenPos = camera.WorldToScreenPoint(target.position);
    16.         print("target is " + screenPos.x + " pixels from the left");
    17.     }
    18. }
    19.  
    What I have done next is made a rectangle object the child of my enemy. The enemyHealthBar script has then been added to the rectangle object (child of the enemy).

    The script works fine, but with errors and bugs.

    For example, the health bar has a massive offset. And the error code can be seen in the picture.

    Can someone please help me. Thank you.

     
  2. Deleted User

    Deleted User

    Guest

  3. moynzy

    moynzy

    Joined:
    Oct 22, 2014
    Posts:
    82
    Assets/Scripts/Enemy/enemyHealthBar.cs(15,44): error CS0120: An object reference is required to access non-static member `UnityEngine.Camera.WorldToScreenPoint(UnityEngine.Vector3)'
     
  4. KelsoMRK

    KelsoMRK

    Joined:
    Jul 18, 2010
    Posts:
    5,539
    This isn't correct.

    The documentation is misleading "camera" assumes "The camera attached to this GameObject" so if there isn't one (and there probably isn't) then it'll be null. You probably want Camera.main.WorldToScreenPoint
     
  5. Deleted User

    Deleted User

    Guest

    Oh sorry it should be "Camera.main"
     
  6. moynzy

    moynzy

    Joined:
    Oct 22, 2014
    Posts:
    82
    Thanks for reply.

    I have tried what you said.

    Got this error


    NullReferenceException: Object reference not set to an instance of an object
    enemyHealthBar.Update () (at Assets/Scripts/Enemy/enemyHealthBar.cs:15)
     
    Silvaine likes this.
  7. Deleted User

    Deleted User

    Guest

    When is your "target" variable set? It's probably set to null.
     
  8. moynzy

    moynzy

    Joined:
    Oct 22, 2014
    Posts:
    82
    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4. public class enemyHealthBar : MonoBehaviour {
    5.  
    6.     public Transform target;
    7.  
    8.     // Use this for initialization
    9.     void Start () {
    10.         GameObject go = GameObject.FindGameObjectWithTag("Enemy");
    11.         target = go.transform;
    12.     }
    13.  
    14.  
    15.     void Update() {
    16.         Vector3 screenPos =  Camera.main.WorldToScreenPoint(target.position);
    17.         Debug.Log("target is " + screenPos.x + " pixels from the left");
    18.     }
    19. }
    It shouldnt be set to null

    I've also tried Awake as well.
     
    Last edited: Nov 19, 2014
  9. Deleted User

    Deleted User

    Guest

    Does the new script return an error?

    The problem I see with it now is that FindGameObjectWithTag will always return the first game object it finds which might not be the game object you want to attach your health bar to. How are you creating your health bars?
     
  10. moynzy

    moynzy

    Joined:
    Oct 22, 2014
    Posts:
    82
    so i should use get game component instead as a reference to "Player"?

    My health bar is basically a rectangle, childed to the enemy.

    You can see it in the picture.
     
  11. Deleted User

    Deleted User

    Guest

    Try this:

    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3. public class enemyHealthBar : MonoBehaviour {
    4.     Transform target;
    5.     // Use this for initialization
    6.     void Start () {
    7.         target = transform.parent;
    8.     }
    9.     void Update() {
    10.         Vector3 screenPos =  Camera.main.WorldToScreenPoint(target.position);
    11.         Debug.Log("target is " + screenPos.x + " pixels from the left");
    12.     }
    13. }
    Tell me if it returns any error, but it shouldn't.
     
  12. moynzy

    moynzy

    Joined:
    Oct 22, 2014
    Posts:
    82

    Fixes the offset problem :p

    But!

    Code (CSharp):
    1.         Vector3 screenPos =  Camera.main.WorldToScreenPoint(target.position);
    2.  
    this causes error:
     
  13. KelsoMRK

    KelsoMRK

    Joined:
    Jul 18, 2010
    Posts:
    5,539
    transform.parent is null if the GameObject isn't a child of anything.
     
  14. moynzy

    moynzy

    Joined:
    Oct 22, 2014
    Posts:
    82
    The game object, is a child of the enemy though.
     
  15. KelsoMRK

    KelsoMRK

    Joined:
    Jul 18, 2010
    Posts:
    5,539
    In either case - something's null on line 10. Go forth and debug!
     
  16. moynzy

    moynzy

    Joined:
    Oct 22, 2014
    Posts:
    82
    Yes sir, thanks for the pointers :D
     
  17. moynzy

    moynzy

    Joined:
    Oct 22, 2014
    Posts:
    82
    Sorry to disturb you but i can't seem to do it.

    This line is is the problem and I do not know why.
     
  18. Suddoha

    Suddoha

    Joined:
    Nov 9, 2013
    Posts:
    2,824
    Assuming you've follwed everything correctly, i think the only thing that might have happened is that you removed the tag "MainCamera" from your camera and do not have any other camera tagged with it.

    If not, your target has to be 'null'.

    If you still use the code example from @supremegrandruler, remove or comment out the lines in Update (only from Update!) and insert

    Code (CSharp):
    1. if (target == null)
    2.     Debug.Log("target is null");
    3. if (Camera.main == null)
    4.     Debug.Log("camera is null");
    The console will tell you what's null.
     
    Deleted User likes this.
  19. moynzy

    moynzy

    Joined:
    Oct 22, 2014
    Posts:
    82
    YOU ARE A LIVE SAVER!
     
  20. moynzy

    moynzy

    Joined:
    Oct 22, 2014
    Posts:
    82
    @Suddoha the code works now.

    For the health bar to be successful, does it need to be made on the On GUI function?

    I'm going for something like this.
     
  21. Suddoha

    Suddoha

    Joined:
    Nov 9, 2013
    Posts:
    2,824
    The capital letters and the quick response make me think it's pure sarcasm, something like 'you don't say, tell me something new'.

    If not, tell us what caused the exception. The other guys told you the same just without code, as it's easy to tackle down null reference exceptions with debugs. I usually do the same though (trying to give an idea with textual explanation), as it's best to figure these things out by yourself but you were already looking for a solution quite some time.

    *edit
    Depends which Unity version you use. New GUI system or the old one?
     
  22. moynzy

    moynzy

    Joined:
    Oct 22, 2014
    Posts:
    82
    no no that was not a sarcasm comment, it was like my major problem :p Thanks again!
     
  23. moynzy

    moynzy

    Joined:
    Oct 22, 2014
    Posts:
    82
    Im using unity 4.5.5

    I'm familiar with the ONGUI function,



    I dont want to show the enemies health on the onGUI tho.
     
  24. Suddoha

    Suddoha

    Joined:
    Nov 9, 2013
    Posts:
    2,824
    I edited my post while you were responding.

    You could use the new GUI system which came with Unity 4.6(+). I personally haven't used that one by myself and haven't really looked into it, so i can't help much with it.

    If you want to use the 'old system' you will surely need the OnGUI method.
    You could also use a gameObject-based approach, but you need to draw the values either way.
     
  25. moynzy

    moynzy

    Joined:
    Oct 22, 2014
    Posts:
    82
    I'll use the old system and put the enemies health bar on to the ONGUI.

    Then on the OnGUI I can use the
    1. Vector3 screenPos = Camera.main.WorldToScreenPoint(target.position);
    and this should centre it above the players head with some off setts,

    do you think this is a logical approach?
     
  26. Deleted User

    Deleted User

    Guest

    Those are some pretty cool healthbars but no, you don't need to use OnGUI for anything.

    For layering, try playing around with sorting layers.

    I've never done healthbars before but one way I'd go about achieving that look is create 2 textures: one colored one and one black one. Then you could superimpose the colored one on the black one and set its size relative the % of health the character has.
     
  27. Suddoha

    Suddoha

    Joined:
    Nov 9, 2013
    Posts:
    2,824
    It is logical, the question is, does it fit your needs and how well does it work for your game?
    E.g if your objects are hidden by other objects in your world, you have do decide whether you want the health bars to be shown or not and how you're gonna hide them if not.

    @supremegrandruler Looks like he's trying to create a 3D game, do they not only work for 2D projects?
     
  28. Deleted User

    Deleted User

    Guest

    @Suddoha I hadn't thought about that! Good question. I would think they'd still work. Only way is to test it out.
     
  29. Suddoha

    Suddoha

    Joined:
    Nov 9, 2013
    Posts:
    2,824
    There's actually another way which may also be a bit more complex. I've never tried that though, but it came to my mind reading @supremegrandruler 's reply as he mentioned layers.

    It's probably a bit more tricky and requires some advanced stuff:
    Seperate the GUI stuff from the actual scene. Use a second camera to render the GUI-related objects in orthographic mode using layers, but do not move it at all. It may sound easy but i'm not quite sure, but now you could do something similar you'd do with your real GUI approach: Take your objects position and calculate the offset position in front of the second camera, move it accordingly. And so on...

    Though, the better solution before you try that: check out new GUI system. I'm really sure you'll be better off with that.