Quadrant Stepper

Four-directional step selector displayed as an overlay compass widget.

Navigation navigation stepper direction compass selector

Quadrant Stepper example


Contents

1 Overview

2 Properties

3 USS Classes

4 Events

5 Constructors

6 Methods

7 Usage

8 Using the Control

9 Video Demo

10 Credits and Donation

11 External links


Overview

QuadrantStepper is a segmented control that divides its width into equally-sized tap targets. A sliding overlay animates between the selected segment. By default it is created with four equal segments; the option list can be replaced at any time via SetOptions. The overlay sits at 90% of the control’s height (5% inset top and bottom) to create a floating appearance.

Typical use cases:

  • Tab bar or mode switcher
  • Category or filter selector
  • Any fixed-option segmented navigation control

Properties

Name Description Options
SelectedIndex Gets or sets the index of the currently selected segment. int
SelectedText Gets the label text of the currently selected segment. string (read-only)

USS Custom Properties

Name Description Default
--quadrantStepper-animation-duration-ms Duration of the sliding overlay animation in milliseconds. Defined in package USS

USS Classes

Class Description
quadrantStepper Root element.
quadrantStepper__overlay The sliding highlight overlay. Absolutely positioned. Transitions between segments.
quadrantStepper__segments Flex row container holding all segment elements.
quadrantStepper__segment Individual segment tap target. Flex-grows equally to divide available width.
quadrantStepper__label Text label inside each segment.
is-selected Modifier applied to the currently selected segment.

Events

Name Description Arguments
SelectionChanged Fired when the selected segment changes via tap or programmatic call (unless suppressed). int index, string text

Constructors

Signature Description
QuadrantStepper() Creates a stepper with four default options ("1", "2", "3", "4").
QuadrantStepper(IReadOnlyList<string> options) Creates a stepper with the provided option labels.

Methods

Signature Description
SetOptions(IReadOnlyList<string> options) Replaces all segment labels. Resets selection to index 0.
SetOptions(IReadOnlyList<string> options, int defaultIndex) Replaces all segment labels and sets the initial selection to defaultIndex.
bool SetOptions(IReadOnlyList<string> options, string defaultText) Replaces labels and attempts to select the segment matching defaultText. Returns true if the text was found and selected.
SetSelectedIndex(int index) Selects the segment at index with animation and fires SelectionChanged.
SetSelectedIndex(int index, bool notify, bool animate) Selects the segment at index with optional event notification and animation.
bool TrySetSelectedText(string text, bool notify, bool animate) Selects the segment whose label matches text. Returns false if not found.
ForceUnselect() Removes the selection without firing SelectionChanged. The overlay is hidden.

Usage

Add the control to your scene using:

GameObject -> UI Toolkit -> Extensions -> Quadrant Stepper

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 -> Quadrant Stepper 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:QuadrantStepper options="About,Goals,Settings,Done" />
</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

Mode Switcher

using UnityEngine;
using UnityEngine.UIElements;
using UnityUIToolkit.Extensions;
using System.Collections.Generic;

public class ModeController : MonoBehaviour
{
    [SerializeField] private UIDocument _document;

    private QuadrantStepper _modeStepper;

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

        var modes = new List<string> { "Daily", "Weekly", "Monthly", "All Time" };
        _modeStepper = new QuadrantStepper(modes);

        // Default to "Weekly" without firing the event
        _modeStepper.SetOptions(modes, defaultIndex: 1);

        _modeStepper.SelectionChanged += (index, text) =>
        {
            Debug.Log($"Mode changed to [{index}] {text}");
            LoadData(text);
        };

        root.Q<VisualElement>("filterContainer").Add(_modeStepper);
    }

    private void LoadData(string period)
    {
        Debug.Log($"Loading data for period: {period}");
    }

    public void ResetToDefault()
    {
        // Restore to "Daily" silently, no animation
        _modeStepper.SetSelectedIndex(0, notify: false, animate: false);
    }
}

Restoring Saved State

// Restore selection from saved preference
string savedMode = PlayerPrefs.GetString("selectedMode", "Weekly");
bool found = _modeStepper.TrySetSelectedText(savedMode, notify: false, animate: false);
if (!found)
    _modeStepper.SetSelectedIndex(0, notify: false, animate: false);

Video Demo

Example Scenes

This control is demonstrated in the following package examples:


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.
  • Step Wizard — A multi-step wizard flow with a step progress bar and per-step inputs.