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.

Attributes

AttributeDescription
Cell Settings
Cell SizeThe value each cell represents (e.g., 100 for 100 HP per cell).
Max ValueMaximum total value. Cell count is calculated as MaxValue / CellSize.
Cell GapGap in pixels between cells.
Cell AngleAngle of cell slant in degrees. 0 = vertical edges, positive = right slant.
Animation Settings
Instant PositiveIf enabled, positive value changes are shown instantly without animation.
Instant NegativeIf enabled, negative value changes are shown instantly without animation.
Update FrequencyInterval in milliseconds between animation updates.
StepHow much the progress bar moves per update (0-1 range).
First DelayDelay before the first bar starts moving.
Second DelayDelay before the second bar starts moving.
Progress Settings
ProgressArray of progress segments. Each has CurrentValue, TargetValue, and Color. Set via UXML.
IndicatorIndicator segment shown behind progress segments.
Appearance
Background ColorColor of the cell backgrounds.
Empty ColorColor of empty (unfilled) cell portions.
Fill ColorColor of the first segment (for single-segment use).
Indicator Auto ColorWhen enabled, indicator color automatically switches between positive/negative colors.
Indicator Color PositiveIndicator color when showing a positive change.
Indicator Color NegativeIndicator color when showing a negative change.

Progress Segment Attributes

Each element in the Progress array has:

AttributeDescription
CurrentValueCurrent fill value (0-1). Don't edit directly—use TargetValue instead.
TargetValueTarget fill value (0-1). Set this to change the fill level.
ColorColor of this progress segment.

Custom USS Properties

Customize appearance by overriding these USS properties in your stylesheet.

PropertyDescription
--celled-progress-bg-colorBackground color of cells.
--celled-progress-empty-colorColor of empty cell portions.
--celled-progress-fill-colorColor of the first segment.
--celled-progress-indicator-positive-colorIndicator color for positive changes.
--celled-progress-indicator-negative-colorIndicator color for negative changes.
--progress-color-0 to --progress-color-9Colors for individual segments (up to 10).

UXML Usage

Single Segment

xml
<CupkekGames.Luna.CelledProgressBar name="health-bar" max-value="1000" cell-size="100" cell-gap="4" cell-angle="0" style="width: 500px; height: 80px;" />

Multi-Segment with Colors (UXML)

Set segments directly in UXML using the progress attribute. Format: CurrentValue|TargetValue|ColorHexRGBA| separated by commas.

xml
<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:

  • Segment 0: Green (#53E653) - Health
  • Segment 1: Cyan (#4CDCFF) - Shield
  • Segment 2: Gold (#FFD933) - Armor

C# Examples

Basic Usage

csharp
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(); } }

Multi-Segment (Overwatch Style)

When using UXML to define segments with colors, the code becomes simpler:

csharp
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(); } }

How Cell Rendering Works

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 cells

With 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.

Public Methods

PlayProgress

Starts the animation to visually apply current Progress values.

csharp
public void PlayProgress()

PlayIndicator

Starts the animation to visually apply the Indicator value.

csharp
public void PlayIndicator()

SetIndicatorStyle

Manually set indicator color style. Usually handled automatically.

csharp
public void SetIndicatorStyle(bool positive)

Settings

Theme

Light

Contrast

Material

Dark

Dim

Material Dark

System

Sidebar(Light & Contrast only)

Light
Dark

Font Family

DM Sans

Wix

Inclusive Sans

AR One Sans

Direction

LTR
RTL