Unity new UI Toolkit progress bar

Viewed 3825

I have been working with the new Unity UI Toolkit recently (Unity 2021.1), but noticed that the UI Builder does not include a definition for a Progress Bar. This seems like such a standard part of games (health stats, etc) that I was shocked both to realize there was no built-in component and that I couldn't find a guide on it. I'm convinced I must be looking in the wrong places, and hoping someone can point me in the right direction.

My current approach was to use the Slider component and try to style via a custom USS sheet. However, I noticed that the new UI system is different than the old one, and has no way to specify the "overlay" colour. Any suggestions on how to handle this? I have seen screenshots of the UI Toolkit Samples where a Progress Bar was included in the samples; however, the current Samples do not have that.

2 Answers

EDIT : latest versions of Unity finally includes a runtime ProgressBar. See @tenuki answer.

UI Toolkit will include more built-in controls in Unity 2021.2 (when it will be included in Unity "core").

In the mean time, you might be better off not using the Slider component, which doesn't correspond to a "progress bar" use case.


The most simple way to achieve this, would be to have a "Background" and an "Overlay" element. The overlay would be a child of the background element.

Then, you can set the width of the Overlay element in per-cent units.

This would like this in the UI Builder : enter image description here

ProgressBar.uxml :

<ui:UXML xmlns:ui="UnityEngine.UIElements" xmlns:uie="UnityEditor.UIElements" xsi="http://www.w3.org/2001/XMLSchema-instance" engine="UnityEngine.UIElements" editor="UnityEditor.UIElements" noNamespaceSchemaLocation="../../../UIElementsSchema/UIElements.xsd" editor-extension-mode="False">
<Style src="ProgressBar.uss" />
<ui:VisualElement name="Background" class="progressBar--background" style="flex-grow: 1;">
    <ui:VisualElement name="Overlay" class="progressBar--overlay" style="width: 50%; height: 100%;" />
</ui:VisualElement>
</ui:UXML>

ProgressBar.uss :

.progressBar--overlay {
    background-color: rgba(243, 19, 77, 255);
}

/* optional */
.progressBar--background {
    border-left-color: rgba(103, 10, 10, 255);
    border-right-color: rgba(103, 10, 10, 255);
    border-top-color: rgba(103, 10, 10, 255);
    border-bottom-color: rgba(103, 10, 10, 255);
    border-left-width: 5px;
    border-right-width: 5px;
    border-top-width: 5px;
    border-bottom-width: 5px;
    border-top-right-radius: 20px;
    border-bottom-right-radius: 20px;
    overflow: hidden;
    border-top-left-radius: 20px;
}

Finally, in your code, you can set the width of the overlay element :

VisualElement progressBarOverlayElement = somePartOfYourUIHierarchy.Q("Overlay");
progressBarOverlayElement.style.width = new StyleLength(Length.Percent(30));

A little tip : you can achieve basic masking by disabling overflow on the topper elements.

Here's the background element of our progress bar, with overflow enabled : Background root element with overflow enabled

Now with overflow set to hidden : Background root element with overflow set to hidden

This might inspire you to do more complex stuff inside the root element of your progress bar.


There's a thread here discussing the multiple solutions available, in the UI Toolkit forum. It seems there still is no commonly agreed way to achieve this, but you might find more interesting tips there (e.g. complex-shaped masking using SVG assets).

Related