This example uses the Progress Bar component with a custom Shader Graph material for enhanced visuals. For creating fully custom progress bar types, see Architecture.
This demo showcases an RPG-style health bar with custom shader effects for enhanced visual appeal.
The RPG Demo demonstrates how to combine Luna's Progress Bar system with custom shaders to create visually stunning health bars commonly seen in RPG games. This approach allows for effects that go beyond what's possible with USS styling alone.
Create a custom UI shader using Shader Graph for the progress bar fill.
Create new Shader Graph: Right-click in Project → Create → Shader Graph → URP → Sprite Unlit (or Canvas for UI)
Add properties to the Blackboard:
Fill (Float, Range 0-1) — Controls fill amountMainColor (Color) — Base fill colorGlowColor (Color) — Edge glow colorGlowIntensity (Float) — Glow strengthBuild the graph:
Example node setup:
UV (X) ──→ Step ──→ Multiply ──→ Base Color
↑
Fill
UV (X) ──→ Subtract (Fill) ──→ Abs ──→ One Minus ──→ Saturate ──→ Multiply (GlowColor) ──→ Add to BaseUse the shader material on the progress bar's fill element via USS:
.rpg-health-bar .progress-fill {
background-image: url("project://database/Assets/Materials/RPGHealthBar.mat");
}Or apply programmatically:
var fill = progressBar.Q(className: "progress-fill");
fill.style.backgroundImage = new StyleBackground(yourMaterial.mainTexture);Update the shader's fill parameter when the progress bar value changes:
using UnityEngine;
using UnityEngine.UIElements;
using CupkekGames.Luna;
public class RPGHealthBarController : MonoBehaviour
{
[SerializeField] private Material _healthBarMaterial;
private ProgressBar _healthBar;
private static readonly int FillProperty = Shader.PropertyToID("_Fill");
private void Start()
{
var root = GetComponent<UIDocument>().rootVisualElement;
_healthBar = root.Q<ProgressBar>("health-bar");
// Subscribe to value changes
_healthBar.RegisterCallback<GeometryChangedEvent>(OnProgressChanged);
}
private void OnProgressChanged(GeometryChangedEvent evt)
{
// Sync shader fill with progress bar value
float currentValue = _healthBar.Progress[0].CurrentValue;
_healthBarMaterial.SetFloat(FillProperty, currentValue);
}
public void TakeDamage(float amount)
{
_healthBar.Progress[0].TargetValue -= amount;
_healthBar.Indicator.TargetValue = _healthBar.Progress[0].TargetValue;
_healthBar.UpdateProgressSegments();
_healthBar.PlayProgress();
_healthBar.PlayIndicator();
}
}MaterialPropertyBlock for per-instance shader properties when you have multiple health bars_Time in the shaderSettings
Theme
Light
Contrast
Material
Dark
Dim
Material Dark
System
Sidebar(Light & Contrast only)
Font Family
DM Sans
Wix
Inclusive Sans
AR One Sans
Direction