Masking is a technique used to control which portions of a UI element are visible. Within UI Toolkit, you can apply the USS property overflow: hidden to hide any parts of an element that extend beyond its parent.
Refer to the official Unity documentation.
This tutorial focuses solely on implementing the masking technique—not on creating the entire progress bar.
To enable masking with custom shapes, you'll use SVG. To apply an SVG image as a background, you must install the com.unity.vectorgraphics package.
The SVG background image will be applied to the parent element.
Below is the SVG used in this example. Feel free to download and use it:
Import settings of the SVG:

Let's set up simple parent-child elements for the masking example:
<engine:VisualElement class="progress-container">
<engine:VisualElement class="progress-fill" />
</engine:VisualElement>.progress-container {
flex: 1;
overflow: hidden;
background-image: url('overwatchCell.svg');
background-repeat: repeat-x;
background-position-x: left 0px;
background-position-y: top 0px;
background-size: 20px 100%; /* Control the width and height; the width determines how many times the background image repeats. */
}
.progress-fill {
height: 100%;
width: 80%; /* Determines the fill amount */
}Use these functions to adjust the background image size, which in turn determines the number of repeats. And set the width of the fill element to control the fill amount.
private void SetBackgroundImageWidth(int widthInPixels)
{
// Update the background size of the progress container.
// Set the width in pixels and the height to 100% of the container.
_progressContainer.style.backgroundSize = new BackgroundSize(
new Length(widthInPixels, LengthUnit.Pixel),
Length.Percent(100)
);
}
public void SetBackgroundImageRepeatAmount(int repeatAmount)
{
// Retrieve the current width of the progress container.
float width = _progressContainer.contentRect.width;
// Ensure the width is valid (not NaN and greater than zero).
// The contentRect is not calculated at first frames, so be careful.
// You might have to manually call SetBackgroundImageWidth if you need to set the width at the start.
if (float.IsNaN(width) || width <= 0)
{
return;
}
// Calculate the width for a single background cell, rounding to the nearest pixel.
int cellWidth = (int)(width / repeatAmount + 0.5f);
// Apply the calculated cell width to update the background image size.
SetBackgroundImageWidth(cellWidth);
}
public void SetFillAmount(float fillAmount)
{
// Make sure fillAmount is within the range [0, 1].
fillAmount = Mathf.Clamp01(fillAmount);
// Update the width of the fill element.
_progressFill.style.width = Length.Percent(fillAmount * 100);
}Settings
Theme
Light
Contrast
Material
Dark
Dim
Material Dark
System
Sidebar(Light & Contrast only)
Font Family
DM Sans
Wix
Inclusive Sans
AR One Sans
Direction