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.

Overview

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.

Features

  • Shader-based rendering — Custom visual effects like gradients, glows, and animated patterns
  • Smooth animations — Luna's built-in animation system for value transitions
  • Indicator preview — Shows damage/heal amounts before applying
  • Customizable appearance — Full control over colors, effects, and timing

Implementation

Step 1: Create the Shader Graph

Create a custom UI shader using Shader Graph for the progress bar fill.

  1. Create new Shader Graph: Right-click in Project → Create → Shader Graph → URP → Sprite Unlit (or Canvas for UI)

  2. Add properties to the Blackboard:

    • Fill (Float, Range 0-1) — Controls fill amount
    • MainColor (Color) — Base fill color
    • GlowColor (Color) — Edge glow color
    • GlowIntensity (Float) — Glow strength
  3. Build the graph:

    • Use UV node's X channel to compare against Fill property
    • Use Step or Smoothstep for the fill cutoff
    • Calculate edge glow by measuring distance from fill edge
    • Multiply colors and combine outputs

Example node setup:

UV (X) ──→ Step ──→ Multiply ──→ Base Color Fill UV (X) ──→ Subtract (Fill) ──→ Abs ──→ One Minus ──→ Saturate ──→ Multiply (GlowColor) ──→ Add to Base
  1. Save and create Material from the shader

Step 2: Apply to Progress Bar

Use the shader material on the progress bar's fill element via USS:

css
.rpg-health-bar .progress-fill { background-image: url("project://database/Assets/Materials/RPGHealthBar.mat"); }

Or apply programmatically:

csharp
var fill = progressBar.Q(className: "progress-fill"); fill.style.backgroundImage = new StyleBackground(yourMaterial.mainTexture);

Step 3: Sync Shader with Progress Bar

Update the shader's fill parameter when the progress bar value changes:

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

Tips

Performance

  • Use MaterialPropertyBlock for per-instance shader properties when you have multiple health bars
  • Consider using a shared material for all health bars of the same type

Visual Polish

  • Add subtle animation to the glow effect using _Time in the shader
  • Use the indicator bar to show incoming damage with a different color
  • Add particle effects for critical hits or healing

Accessibility

  • Ensure sufficient contrast between filled and empty states
  • Consider adding numerical display alongside the bar
  • Test with colorblind-friendly palettes

See Also

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