CelledProgressBar is a linear progress bar that renders discrete cell segments using UI Toolkit's mesh generation API. It's ideal for Overwatch-style health bars with angled cells, multi-segment displays (health/shield/armor), and damage indicators.
| Attribute | Description |
|---|---|
| Cell Settings | |
| Cell Size | The value each cell represents (e.g., 100 for 100 HP per cell). |
| Max Value | Maximum total value. Cell count is calculated as MaxValue / CellSize. |
| Cell Gap | Gap in pixels between cells. |
| Cell Angle | Angle of cell slant in degrees. 0 = vertical edges, positive = right slant. |
| Animation Settings | |
| Instant Positive | If enabled, positive value changes are shown instantly without animation. |
| Instant Negative | If enabled, negative value changes are shown instantly without animation. |
| Update Frequency | Interval in milliseconds between animation updates. |
| Step | How much the progress bar moves per update (0-1 range). |
| First Delay | Delay before the first bar starts moving. |
| Second Delay | Delay before the second bar starts moving. |
| Progress Settings | |
| Progress | Array of progress segments. Each has CurrentValue, TargetValue, and Color. Set via UXML. |
| Indicator | Indicator segment shown behind progress segments. |
| Appearance | |
| Background Color | Color of the cell backgrounds. |
| Empty Color | Color of empty (unfilled) cell portions. |
| Fill Color | Color of the first segment (for single-segment use). |
| Indicator Auto Color | When enabled, indicator color automatically switches between positive/negative colors. |
| Indicator Color Positive | Indicator color when showing a positive change. |
| Indicator Color Negative | Indicator color when showing a negative change. |
Each element in the Progress array has:
| Attribute | Description |
|---|---|
| CurrentValue | Current fill value (0-1). Don't edit directly—use TargetValue instead. |
| TargetValue | Target fill value (0-1). Set this to change the fill level. |
| Color | Color of this progress segment. |
Customize appearance by overriding these USS properties in your stylesheet.
| Property | Description |
|---|---|
| --celled-progress-bg-color | Background color of cells. |
| --celled-progress-empty-color | Color of empty cell portions. |
| --celled-progress-fill-color | Color of the first segment. |
| --celled-progress-indicator-positive-color | Indicator color for positive changes. |
| --celled-progress-indicator-negative-color | Indicator color for negative changes. |
| --progress-color-0 to --progress-color-9 | Colors for individual segments (up to 10). |
<CupkekGames.Luna.CelledProgressBar
name="health-bar"
max-value="1000"
cell-size="100"
cell-gap="4"
cell-angle="0"
style="width: 500px; height: 80px;" />Set segments directly in UXML using the progress attribute. Format: CurrentValue|TargetValue|ColorHexRGBA| separated by commas.
<CupkekGames.Luna.CelledProgressBar
name="health-bar"
max-value="1000"
cell-size="100"
cell-gap="4"
progress="1|1|53E653FF|,0|0|4CDCFFFF|,0|0|FFD933FF|"
style="width: 500px; height: 80px;" />This creates 3 segments:
using UnityEngine;
using UnityEngine.UIElements;
using CupkekGames.Luna;
public class CelledProgressDemo : MonoBehaviour
{
private CelledProgressBar _healthBar;
private void Start()
{
var root = GetComponent<UIDocument>().rootVisualElement;
_healthBar = root.Q<CelledProgressBar>("health-bar");
// Initialize at full health
_healthBar.InstantPositive = true;
_healthBar.Progress[0].TargetValue = 1f;
_healthBar.Indicator.TargetValue = 1f;
_healthBar.PlayProgress();
_healthBar.PlayIndicator();
_healthBar.InstantPositive = false;
}
public void TakeDamage(float normalizedAmount)
{
_healthBar.Progress[0].TargetValue -= normalizedAmount;
_healthBar.Indicator.TargetValue = _healthBar.Progress[0].TargetValue;
_healthBar.PlayProgress();
_healthBar.PlayIndicator();
}
}When using UXML to define segments with colors, the code becomes simpler:
using UnityEngine;
using UnityEngine.UIElements;
using CupkekGames.Luna;
public class OverwatchHealthBar : MonoBehaviour
{
private CelledProgressBar _healthBar;
private int _health = 1000;
private int _shield = 0;
private int _armor = 0;
private const int BaseMaxHealth = 1000;
private void Start()
{
var root = GetComponent<UIDocument>().rootVisualElement;
_healthBar = root.Q<CelledProgressBar>("health-bar");
// Segments and colors are already set via UXML progress attribute
UpdateProgressBar();
}
public void TakeDamage(int damage)
{
// Damage order: Armor → Shield → Health
if (_armor > 0)
{
int armorDamage = Mathf.Min(_armor, damage);
_armor -= armorDamage;
damage -= armorDamage;
}
if (damage > 0 && _shield > 0)
{
int shieldDamage = Mathf.Min(_shield, damage);
_shield -= shieldDamage;
damage -= shieldDamage;
}
if (damage > 0)
{
_health = Mathf.Max(0, _health - damage);
}
UpdateProgressBar();
}
private void UpdateProgressBar()
{
float total = BaseMaxHealth + _shield + _armor;
_healthBar.MaxValue = total;
// Calculate normalized values
float healthNorm = _health / total;
float shieldNorm = _shield / total;
float armorNorm = _armor / total;
// Update segments (colors already set from UXML)
var segments = _healthBar.Progress;
segments[0].TargetValue = healthNorm;
segments[1].TargetValue = shieldNorm;
segments[2].TargetValue = armorNorm;
_healthBar.Data.Indicator.TargetValue = healthNorm + shieldNorm + armorNorm;
_healthBar.PlayProgress();
_healthBar.PlayIndicator();
}
}CelledProgressBar divides the bar into discrete cells based on MaxValue / CellSize:
MaxValue = 1000, CellSize = 100 → 10 cells
┌──┬──┬──┬──┬──┬──┬──┬──┬──┬──┐
│▓▓│▓▓│▓▓│▓▓│▓▓│▓▓│▓▓│░░│░░│░░│ 70% filled
└──┴──┴──┴──┴──┴──┴──┴──┴──┴──┘
▓▓ = Filled cells (health/shield/armor colors)
░░ = Empty cellsWith cell-angle > 0, cells get a slanted appearance:
╱▓▓╱▓▓╱▓▓╱▓▓╱▓▓╱▓▓╱▓▓╱░░╱░░╱░░╱
Multi-segment fills are stacked within cells—each segment continues where the previous one ended, creating layered health bar effects.
Starts the animation to visually apply current Progress values.
public void PlayProgress()Starts the animation to visually apply the Indicator value.
public void PlayIndicator()Manually set indicator color style. Usually handled automatically.
public void SetIndicatorStyle(bool positive)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