Tags: unity, ui, hud, health-bars, damage-numbers, pause-menu, input-mapping, tooltips, game-dev Last updated: 2026-06-27

Game UI / HUD Cheatsheet

Quick Reference

UI ElementUnity SystemKey Component
Health baruGUI / UI ToolkitSlider, Image (fill)
Damage numbersuGUI + World SpaceTextMeshPro, Canvas
Pause menuuGUI overlayCanvas, Panel, Button
Input mappingUI Toolkit / uGUIInput System rebinding
TooltipsuGUITooltip trigger + panel
MinimapRenderTexture + RawImageCamera, RawImage

Unity UI Systems

SystemBest ForWhen
uGUI (Canvas)Most projects, stableDefault choice
UI ToolkitEditor tools, data-driven UINewer projects (2021+)
IMGUIDebug overlays, editor scriptsNever for runtime

Health Bars

World-Space Health Bar (Overhead)

public Slider healthBar;
public Transform target;
public Vector3 offset = new(0, 2.5f, 0);

void LateUpdate() {
    healthBar.transform.position = target.position + offset;
    healthBar.transform.forward = Camera.main.transform.forward;
}

public void SetHealth(float current, float max) {
    healthBar.value = current / max;
}

Screen-Space Health Bar (HUD)

public Image healthFill;
public TextMeshProUGUI healthText;

public void UpdateHealth(float current, float max) {
    healthFill.fillAmount = current / max;
    healthText.text = $"{current:0}/{max:0}";
    healthFill.color = Color.Lerp(Color.red, Color.green, current / max);
}

IEnumerator SmoothDrain(float target) {
    while (Mathf.Abs(healthFill.fillAmount - target) > 0.001f) {
        healthFill.fillAmount = Mathf.Lerp(
            healthFill.fillAmount, target, Time.deltaTime * 5f);
        yield return null;
    }
}

Damage Decay (Delayed Damage Bar)

public Image frontBar, backBar;

public void TakeDamage(float newHealth) {
    frontBar.fillAmount = newHealth;
    StopCoroutine("DecayBackBar");
    StartCoroutine(DecayBackBar(0.5f));
}

IEnumerator DecayBackBar(float delay) {
    yield return new WaitForSeconds(delay);
    while (backBar.fillAmount > frontBar.fillAmount) {
        backBar.fillAmount = Mathf.MoveTowards(
            backBar.fillAmount, frontBar.fillAmount, Time.deltaTime * 2f);
        yield return null;
    }
}

Damage Numbers

Floating Damage (World Space)

public TextMeshPro damageText;

void Start() {
    GetComponent<Canvas>().worldCamera = Camera.main;
    StartCoroutine(FloatAndFade());
}

IEnumerator FloatAndFade() {
    float duration = 1.5f, elapsed = 0f;
    Vector3 start = transform.position;
    Vector3 end = start + Vector3.up * 2f +
                  Random.insideUnitSphere * 0.5f;
    Color color = damageText.color;

    while (elapsed < duration) {
        elapsed += Time.deltaTime;
        float t = elapsed / duration;
        transform.position = Vector3.Lerp(start, end, t);
        color.a = Mathf.Lerp(1f, 0f, t);
        damageText.color = color;
        yield return null;
    }
    Destroy(gameObject);
}

Pool with ObjectPool<DamageNumber> (see Performance Optimization sheet).

Pause Menu

Time Scale Pause

public GameObject pausePanel;

void Update() {
    if (Input.GetKeyDown(KeyCode.Escape)) {
        if (Time.timeScale == 0f) Resume();
        else Pause();
    }
}

public void Pause() {
    pausePanel.SetActive(true);
    Time.timeScale = 0f;
    Cursor.visible = true;
    Cursor.lockState = CursorLockMode.None;
}

public void Resume() {
    pausePanel.SetActive(false);
    Time.timeScale = 1f;
    Cursor.visible = false;
    Cursor.lockState = CursorLockMode.Locked;
}

Input Blocking

if (EventSystem.current.IsPointerOverGameObject())
    return;   # Ignore click — hovering UI

Input Rebinding Screen

using UnityEngine.InputSystem;

public InputActionReference actionRef;
public TextMeshProUGUI bindingText;

public void StartRebind() {
    var rebind = actionRef.action.PerformInteractiveRebinding()
        .OnMatchWaitForAnother(0.1f)
        .OnComplete(op => {
            bindingText.text = actionRef.action.GetBindingDisplayString();
            op.Dispose();
        })
        .Start();
}

string json = actionRef.action.SaveBindingOverridesAsJson();
PlayerPrefs.SetString("InputOverrides", json);

Tooltips

Hover Detection

public class TooltipTrigger : MonoBehaviour,
    IPointerEnterHandler, IPointerExitHandler {

    public string header;
    [TextArea] public string content;

    public void OnPointerEnter(PointerEventData e)
        => TooltipSystem.Show(content, header);
    public void OnPointerExit(PointerEventData e)
        => TooltipSystem.Hide();
}

Tooltip System (Singleton)

public class TooltipSystem : MonoBehaviour {
    public GameObject tooltipPanel;
    public TextMeshProUGUI headerText, contentText;
    public float showDelay = 0.5f;

    public void Show(string content, string header = "") {
        StartCoroutine(DelayedShow(content, header));
    }

    IEnumerator DelayedShow(string content, string header) {
        yield return new WaitForSeconds(showDelay);
        headerText.text = header;
        contentText.text = content;
        tooltipPanel.SetActive(true);
    }

    public void Hide() => tooltipPanel.SetActive(false);
}

Tooltip Positioning

void LateUpdate() {
    Vector2 mousePos = Input.mousePosition;
    rectTransform.pivot = new Vector2(
        mousePos.x / Screen.width, mousePos.y / Screen.height);
    rectTransform.position = mousePos;
}

Minimap

public Camera minimapCam;
public Transform player;

void LateUpdate() {
    Vector3 pos = player.position;
    pos.y = minimapCam.transform.position.y;
    minimapCam.transform.position = pos;
    minimapCam.transform.rotation = Quaternion.Euler(
        90, player.eulerAngles.y, 0);
}

UI Navigation (Controller / Keyboard)

public GameObject firstButton;
void OnEnable() {
    EventSystem.current.SetSelectedGameObject(firstButton);
}

Navigation nav = button.navigation;
nav.mode = Navigation.Mode.Explicit;
nav.selectOnUp = buttonAbove;
nav.selectOnDown = buttonBelow;
nav.selectOnLeft = buttonLeft;
nav.selectOnRight = buttonRight;
button.navigation = nav;