derlin of Unity
4/26/2017 - 6:48 AM

Display a health bar above the player in 3D

Display a health bar above the player in 3D

Structure:

Canvas:
↳ ...
↳ BarContainer - UI.Image:
    * Image: the container, set it to whatever color and size you need
    * HealthLevelAbovePlayer: the script
  ↳ Bar - UI.Image:
    * The actual bar, set the color and height to whatever and the position to (0,0)
      As long as the height is less than the Container's, it will be automatically 
      centered by the script

Don't forget to change the GetHealth method in the script to update the size of the level.

using UnityEngine;
using UnityEngine.UI;

public class HealthLevelAbovePlayer : MonoBehaviour
{
    private Image[] images;
    private RectTransform levelRectTransform;
    private RectTransform containerRectTransform;

    private float displayFactor;

    private Vector3 levelSize;
    private GameObject player;
    private Vector3 offsetTop;
    private float offsetYTop = .4f;

    void Start()
    {
        containerRectTransform = GetComponent<RectTransform>();
        levelRectTransform = GetComponentsInChildren<RectTransform>()[1];
        player = GameObject.FindGameObjectWithTag("Player");
        images = GetComponentsInChildren<Image>();

        float insets = (containerRectTransform.rect.height - levelRectTransform.rect.height);
        displayFactor = (GetComponent<RectTransform>().rect.width - insets) / 100f;

        levelSize = levelRectTransform.sizeDelta;
        offsetTop = new Vector3(0.0f, player.GetComponent<CapsuleCollider>().height + offsetYTop, 0.0f);

        // add offsets to level bar (for this to work, level must be at position 0,0 in editor)
        insets /= 2f;
        levelRectTransform.localPosition = levelRectTransform.localPosition + new Vector3(insets, -insets, 0);
    }

    void Update()
    {
        float health = GetHealth();
        levelSize.x = health * displayFactor;
        levelRectTransform.sizeDelta = levelSize;

        Vector3 worldPosition = player.transform.position + offsetTop;
        containerRectTransform.position = Camera.main.WorldToScreenPoint(worldPosition);
    }

    float GetHealth()
    {
        // TODO
        return 0f;
    }


    // use this to show/hide the health bar
    void toggleDisplay(bool show)
    {
        foreach (Image image in images)
        {
            image.enabled = show;
        }
    }

}