Unity Term Book
Animation & UI

UI Systems

Unity's UI stack covers classic Unity UI (uGUI) and modern UI Toolkit, plus Canvas, CanvasScaler, and EventSystem — the tools for menus, HUDs, and screens.

Imagine...

A Canvas is a blank sheet in front of the screen — every UI element lives on it. A CanvasScaler is the ruler that shrinks or grows that sheet when the resolution changes (1080p down to a phone). An EventSystem is a virtual mouse that decides which element was clicked. Missing any of the three means UI that does not show, does not scale, or does not click.

The concept in detail

A Canvas is the root container for all UI. Three render modes: Screen Space - Overlay (always on top of the game, camera-independent), Screen Space - Camera (rendered through a specific camera, affected by depth/post-process), and World Space (a 3D object in the scene — in-world screens, health bars over characters).

CanvasScaler solves multi-resolution. Scale With Screen Size is the usual mode: you design at a Reference Resolution (1920×1080), and the scaler fits the real screen. Match (0=width, 1=height, 0.5=average) picks which axis to prioritize.

EventSystem is the singleton that handles all UI input: clicks, touch, gamepad. It uses a Raycaster (GraphicRaycaster on Canvas, PhysicsRaycaster for World Space) to find the hovered/selected element. There must be exactly one EventSystem in the scene — more than one conflicts.

From Unity 2021+, UI Toolkit is the newer stack built on web ideas (UXML layout, USS styling like HTML/CSS). It outperforms uGUI on complex UI, but integrating with 3D gameplay is harder. uGUI is still the common choice for in-game runtime UI.

A standard Unity UI hierarchy

uGUI (Scene Hierarchy)

📁 Canvas(+ CanvasScaler)

├ 📁 Panel

Image(background)

Text (TMP)

Button

Text (TMP)

└ 📁 HUD

Slider(health)

RawImage(minimap)

📁 EventSystem

Render Modes

Screen Space - Overlay

UI always draws on top of the scene. HUD, inventory, main menu. Unaffected by the camera.

Screen Space - Camera

Renders through a specific Camera. Allows post-processing on UI (blur, bloom).

World Space

UI is a 3D object. Health bars, in-game screens, VR UI. Needs EventSystem + camera raycast.

Hands-on steps

1

Create a basic Canvas

GameObject → UI → Canvas. Unity adds Canvas + CanvasScaler + GraphicRaycaster + EventSystem.

2

Configure CanvasScaler

UI Scale Mode → Scale With Screen Size. Reference Resolution → 1920×1080 (or your target). Match → 0.5.

3

Use RectTransform

UI uses RectTransform instead of Transform. Anchor presets (top-right, stretch full screen...) are the key to responsive layout.

4

Set Sorting Order for multiple Canvases

Canvas → Sort Order: higher numbers draw on top. Tooltips above inventory, dialogs above HUD.

5

Split Canvases to reduce rebatching

Each canvas batches separately. Put static UI (background) on its own Canvas so dynamic UI does not dirty the whole batch.

Interactive simulator

Watch CanvasScaler work — resize the screen and see the UI scale with it.

HP 75/100
⭐ 1280

Game Menu

map

Scale: 1.00 | Reference: 1920×1080

Code example

Basic

Update UI from script — health bar, score text, show/hide panels.

using UnityEngine;
using UnityEngine.UI;
using TMPro;

public class HUDController : MonoBehaviour
{
  [Header("Health")]
  public Slider healthSlider;
  public TMP_Text healthText;

  [Header("Score")]
  public TMP_Text scoreText;

  [Header("Panels")]
  public GameObject menuPanel;
  public GameObject hudPanel;

  public void UpdateHealth(float current, float max)
  {
      healthSlider.value = current / max;
      healthText.text = $"{Mathf.RoundToInt(current)}/{Mathf.RoundToInt(max)}";

      // Tint when HP is low
      healthSlider.fillRect.GetComponent<Image>().color =
          current / max < 0.3f ? Color.red : Color.green;
  }

  public void ShowMenu(bool show)
  {
      menuPanel.SetActive(show);
      hudPanel.SetActive(!show);
      Time.timeScale = show ? 0f : 1f; // Pause while the menu is open
  }

  public void UpdateScore(int score)
  {
      scoreText.text = score.ToString("N0"); // "1,280" format
  }
}

Code example

Advanced

World Space UI — a health bar over a character that always faces the camera.

using UnityEngine;
using UnityEngine.UI;

// Attach to a World Space Canvas — HP bar over a character
public class WorldSpaceHealthBar : MonoBehaviour
{
  public Slider slider;
  public Vector3 offset = new Vector3(0, 2.5f, 0);
  public Transform target;

  Camera cam;

  void Start() => cam = Camera.main;

  void LateUpdate()
  {
      if (target == null) return;

      // Follow the character + offset
      transform.position = target.position + offset;

      // Always face the camera (billboard)
      transform.LookAt(transform.position + cam.transform.rotation * Vector3.forward,
                       cam.transform.rotation * Vector3.up);
  }

  public void SetHealth(float current, float max)
  {
      slider.value = current / max;
      // Hide when HP is full
      gameObject.SetActive(current < max);
  }
}

📌 Quick recap

  • Canvas Overlay: not affected by the camera
  • CanvasScaler: Scale With Screen Size → Reference 1920×1080
  • Only 1 EventSystem in the scene — more causes bugs
  • Split static/dynamic Canvases to avoid expensive rebatching
  • LateUpdate for World Space UI so it follows after physics

⚠️ Common mistakes

  • ❌ The Button does not receive clicks

    Missing EventSystem, or GraphicRaycaster is disabled

    ✅ Ensure an EventSystem exists and the Canvas has a GraphicRaycaster

  • ❌ UI looks different on PC vs phone

    CanvasScaler is not configured

    ✅ Scale With Screen Size + Reference 1920×1080 + Match 0.5