Loading Icon

Animated spinner/loading indicator with configurable speed and colour.

Feedback feedback loading spinner animation indicator

Loading Icon example


Contents

1 Overview

2 Properties

3 USS Classes

4 Events

5 Methods

6 Usage

7 Using the Control

8 Video Demo

9 Credits and Donation

10 External links


Overview

LoadingIcon is a continuously rotating image element used to indicate background work. Rotation is driven by a scheduled callback that fires every 16 ms. An optional blockInteraction flag captures pointer events so the user cannot interact with elements beneath the spinner while it is active.

Typical use cases:

  • Async operation feedback (API calls, data loading)
  • Image upload or file transfer progress indicator
  • Form submission spinner overlay

Properties

This control is configured through method calls. The visibility and animation state are reflected in modifier classes.


USS Classes

Class Description
loadingIcon Root element.
loadingIcon__image The rotating image. Fixed at 40 × 40 px.
loadingIcon--animating Modifier applied while rotation is active.
loadingIcon--visible Modifier applied while the icon is shown. Pair with USS to control opacity or display.

Events

This control does not emit events.


Methods

Signature Description
SetIcon(Texture2D texture) Sets the texture used for the spinning image.
PlayLoading(float customSpeed = 1f, bool blockInteraction = false) Starts the rotation animation. customSpeed is the duration of one full 360° rotation in seconds; lower values spin faster. When blockInteraction is true the control captures all pointer events.
StopLoading() Stops the rotation, releases pointer capture, and removes the --animating and --visible modifiers.

Usage

Add the control to your scene using:

GameObject -> UI Toolkit -> Extensions -> Loading Icon

This creates a UIDocument in the scene (plus a PanelSettings with the default runtime theme, if the project has none) and assigns an editable starter template with demo content, copied to Assets/UI Toolkit Extensions.

A starter template can also be added to an existing document using:

Assets -> Create -> UI Toolkit -> Extensions -> Loading Icon Starter

Alternatively, drag the control into a document from the UI Builder Library (Project -> Custom Controls -> UnityUIToolkit.Extensions) or declare it directly in UXML:

<ui:UXML xmlns:ui="UnityEngine.UIElements" xmlns:ext="UnityUIToolkit.Extensions" editor-extension-mode="False">
    <ext:LoadingIcon name="loading-icon" />
</ui:UXML>

The shared extensions stylesheet is applied automatically when the control is created in the Editor and in Play Mode, so no manual stylesheet reference is needed while authoring. The starter templates also reference the stylesheet explicitly, which covers player builds; for hand-written UXML or code-first UI in builds, add the stylesheet to your UXML or panel theme.


Using the Control

Simple Loading Overlay

using System.Threading.Tasks;
using UnityEngine;
using UnityEngine.UIElements;
using UnityUIToolkit.Extensions;

public class UploadController : MonoBehaviour
{
    [SerializeField] private UIDocument _document;
    [SerializeField] private Texture2D _spinnerTexture;

    private LoadingIcon _spinner;

    private void OnEnable()
    {
        var root = _document.rootVisualElement;

        _spinner = new LoadingIcon();
        _spinner.SetIcon(_spinnerTexture);

        root.Q<VisualElement>("overlayContainer").Add(_spinner);

        root.Q<Button>("uploadButton").clicked += () => _ = StartUpload();
    }

    private async Task StartUpload()
    {
        // 0.8s per rotation, block taps on underlying UI
        _spinner.PlayLoading(customSpeed: 0.8f, blockInteraction: true);

        try
        {
            await UploadFileAsync();
        }
        finally
        {
            _spinner.StopLoading();
        }
    }

    private async Task UploadFileAsync()
    {
        // Simulate async upload
        await Task.Delay(2000);
    }
}

Speed Variants

// Slow, calm indicator — 1.5 seconds per revolution
_spinner.PlayLoading(customSpeed: 1.5f);

// Fast, urgent indicator — 0.4 seconds per revolution
_spinner.PlayLoading(customSpeed: 0.4f);

Video Demo

Example Scenes

This control is demonstrated in the following package example:


Credits and Donation

SimonDarksideJ


UI Toolkit Extensions repository OpenUPM package

Demonstrated In

  • Content Explorer — A full content-browsing screen that composes scroll-snap, collapsible sections, inputs, a loading state and toasts into one layout.