UI Toolkit vs uGUI in Unity 6: Which Should You Use?

Illustration of a glowing game menu panel assembled from modular blocks

Written by

in

Unity has two runtime UI systems, and new developers are often told to use both. uGUI (Canvas, RectTransform, Image, Button) has powered Unity games since 2014. UI Toolkit (UXML, USS, UI Builder) is the newer, web-inspired system that Unity now recommends for most new UI. This guide compares them honestly for Unity 6, then builds the same main menu both ways so you can see the difference, and ends with a clear rule for which one to pick.

The Two Systems at a Glance

uGUI is built from GameObjects. A Canvas holds child objects, each with a RectTransform for layout and components like Image, Text (TextMeshPro) and Button. You design it in the Scene view, animate it with the Animator, and it behaves like the rest of Unity.

UI Toolkit is built from a tree of visual elements that aren’t GameObjects. Layout goes in UXML files (similar to HTML), styling in USS files (similar to CSS), and you design it in the UI Builder window. A single UIDocument component in the scene displays it. It uses flexbox layout, so anyone who has built a web page will recognize it.

UI Toolkit also powers the Unity Editor’s own interface, so learning it pays off for editor tools too.

Feature Comparison

Feature uGUI UI Toolkit
Layout model Anchors, pivots, layout groups Flexbox
Styling Per-object components, prefabs Shared USS stylesheets
Visual editor Scene view UI Builder
World-space UI Yes Newer (added in Unity 6.2)
Animation Animator, any tween library USS transitions, code
Custom shaders / materials Yes Limited
Particles in UI Yes (with tricks) Not directly
Data binding Manual Runtime binding (Unity 6)
Editor tools No Yes
Tutorials and assets available Huge Growing

Building a Menu with uGUI

  1. GameObject > UI > Canvas. Set the Canvas Scaler’s UI Scale Mode to Scale With Screen Size with a reference resolution like 1920×1080, so the menu scales on every screen.
  2. Add a Panel, then a Vertical Layout Group on it (spacing 20, child alignment Middle Center).
  3. Add three Button – TextMeshPro children: Play, Settings, Quit.
  4. Wire them up from a script:
using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEngine.UI;

public class MainMenuUGUI : MonoBehaviour
{
    [SerializeField] Button playButton, settingsButton, quitButton;
    [SerializeField] GameObject settingsPanel;

    void Awake()
    {
        playButton.onClick.AddListener(() => SceneManager.LoadScene("Game"));
        settingsButton.onClick.AddListener(() => settingsPanel.SetActive(true));
        quitButton.onClick.AddListener(Application.Quit);
    }
}

It’s quick and visual. The downside shows up later: changing the button style means editing every button (or every prefab variant), and complex screens become deep GameObject hierarchies.

Building the Same Menu with UI Toolkit

  1. In the Project window, Create > UI Toolkit > UI Document to make MainMenu.uxml. Double-click it to open UI Builder.
  2. Drag in a VisualElement as a container, then three Button elements. Give them names: play, settings, quit. Names are how code finds elements.
  3. In the scene, GameObject > UI Toolkit > UI Document. This creates the UIDocument component and a Panel Settings asset. Assign your UXML as the Source Asset.
  4. In Panel Settings, set Scale Mode to Scale With Screen Size, like the uGUI Canvas Scaler.

The UXML UI Builder produces looks like this:

<ui:UXML xmlns:ui="UnityEngine.UIElements">
  <Style src="MainMenu.uss" />
  <ui:VisualElement class="menu">
    <ui:Button name="play" text="Play" class="menu-button" />
    <ui:Button name="settings" text="Settings" class="menu-button" />
    <ui:Button name="quit" text="Quit" class="menu-button" />
  </ui:VisualElement>
</ui:UXML>

And the script:

using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEngine.UIElements;

[RequireComponent(typeof(UIDocument))]
public class MainMenuToolkit : MonoBehaviour
{
    void OnEnable()
    {
        var root = GetComponent<UIDocument>().rootVisualElement;
        root.Q<Button>("play").clicked     += () => SceneManager.LoadScene("Game");
        root.Q<Button>("settings").clicked += ShowSettings;
        root.Q<Button>("quit").clicked     += Application.Quit;
    }

    void ShowSettings() { /* swap to another UXML or toggle a hidden element */ }
}

Q<T>("name") finds an element by name. Query in OnEnable, not Awake: the UIDocument rebuilds its tree when it’s enabled, so references from Awake can point at elements that no longer exist.

Styling with USS

This is where UI Toolkit shines. Every button shares one stylesheet, including hover and pressed states:

.menu {
    flex-grow: 1;
    justify-content: center;
    align-items: center;
}

.menu-button {
    width: 320px;
    height: 64px;
    margin: 10px;
    font-size: 28px;
    color: white;
    background-color: #2354E8;
    border-radius: 12px;
    border-width: 0;
    transition-duration: 0.15s;
}

.menu-button:hover {
    background-color: #3A6BFF;
    scale: 1.05 1.05;
}

.menu-button:active {
    background-color: #1A3FB0;
}

Change .menu-button once and every button in the game updates. Designers who know CSS can work on UI without touching scenes or prefabs. USS supports a subset of CSS: flexbox, variables (--main-color), pseudo-classes like :hover, :active and :focus, and transitions. There’s no CSS grid, and not every property exists.

🧰 Short on time for UI polish?

Menus, inventories and HUDs are a lot of work to build from scratch. Our roundup of the best Asset Store tools for indie devs includes the UI and workflow assets we think are worth paying for.

See the Asset Store tools list →

Performance

Both systems can be fast or slow depending on how you use them.

  • uGUI rebuilds a whole Canvas’s mesh when anything on it changes. A health bar that updates every frame on the same Canvas as a complex static menu forces the menu to rebuild too. The standard fix is splitting UI into several Canvases: static things on one, frequently changing things on another. Disable Raycast Target on images and text that don’t need clicks.
  • UI Toolkit is retained-mode and generally handles large, complex screens (inventories with hundreds of slots, big lists) with less overhead. Its ListView virtualizes long lists, only creating elements for visible rows. Changing styles in code every frame can still be costly, so prefer toggling USS classes over setting inline styles.

For a typical indie game, either one is fast enough. Profile before choosing based on performance alone.

Which Should You Use?

  • Choose UI Toolkit for menus, settings screens, inventories, HUDs with lots of text and data, and anything with many screens that should share a style. Also for editor tools. It’s where Unity is investing, and it’s the better long-term skill.
  • Choose uGUI for world-space UI on older Unity versions (health bars over enemies, in-game screens), UI with custom shaders or particles, heavily animated UI built with the Animator, or when you’re following a tutorial or using an asset built on it.
  • Mixing is fine. Many Unity 6 projects use UI Toolkit for menus and uGUI for world-space elements. Both can exist in the same scene.

Troubleshooting

UI Toolkit buttons don’t respond to clicks

The scene needs an EventSystem only for uGUI. UI Toolkit handles input itself, but an element on top (a full-screen container) may be blocking clicks. Set picking-mode: ignore on containers that shouldn’t catch the mouse. Also check the UIDocument’s Sort Order if several documents overlap.

NullReferenceException from Q<Button>()

No element with that name exists, or you queried before the document was built. Check the exact name in UI Builder (it’s case-sensitive) and query in OnEnable.

uGUI button doesn’t click

Check there’s an EventSystem in the scene, the Canvas has a Graphic Raycaster, and no transparent Image with Raycast Target on sits above the button. If you use the new Input System, the EventSystem needs the Input System UI Input Module.

UI looks tiny or huge on other resolutions

Set Canvas Scaler (uGUI) or Panel Settings (UI Toolkit) to Scale With Screen Size with a reference resolution, and test in the Game view at several aspect ratios.

Text looks blurry in UI Toolkit

Use a proper font asset (Unity 6 uses the TextCore/TextMeshPro text system in both UI systems) and avoid scaling elements with scale for large size changes. Change font-size instead.

FAQ

Is uGUI deprecated?

No. uGUI is still supported in Unity 6 and widely used. Unity recommends UI Toolkit for new UI, but uGUI isn’t going away soon.

Is UI Toolkit ready for runtime games?

Yes, for most screen-space UI: menus, HUDs and inventories. World-space support arrived in Unity 6.2, and custom shader effects are still easier in uGUI.

Do I need to know CSS to use UI Toolkit?

It helps but isn’t required. UI Builder lets you set every style visually, and USS is a small subset of CSS that’s quick to learn.

Can I use UI Toolkit and uGUI together?

Yes. They can run in the same scene. A common split is UI Toolkit for menus and uGUI for world-space elements.

Does UI Toolkit work with the new Input System?

Yes. UI Toolkit reads input through the Input System package when it’s active, including gamepad navigation.

How do I animate UI Toolkit elements?

Use USS transitions for hover and state changes, and change classes or style values from code for more complex animations.

Comments

Leave a Reply

Your email address will not be published. Required fields are marked *