# Universal Bars PEAK-style universal UMG bars for Unreal Engine 5.7 — one procedural material drives every kind of stat bar (health, stamina, hunger, thirst, oxygen, cold, shield, injury, boss HP, item durability, progress), with a global subsystem API and animated damage / heal / low-value feedback. Everything is **procedural** — no bar textures required. White rounded border, soft corners, dark translucent backdrop, bright flat fill: clean cartoon survival HUD. --- ## 1. Install / enable The plugin lives at `Plugins/UniversalBars/`. It is a project plugin and is enabled by default. After pulling, regenerate project files and build the editor target once (it adds the `UniversalBars` runtime module). Content mounts under `/UniversalBars/`. > New C++ classes (a new module) cannot be hot-loaded by Live Coding — do a full > editor build the first time. --- ## 2. What's inside ``` /UniversalBars/ Materials/ M_UI_UniversalBar master material (Domain=UI, Translucent, procedural SDF) MI_UI_Bar_Health solo green bar MI_UI_Bar_Stamina solo yellow-green bar MI_UI_Bar_Injury striped "broken HP" bar MI_UI_Bar_Shield blue bar + shield overlay MI_UI_Bar_Boss segmented boss bar MI_UI_Bar_PeakCombined HP + hunger + weight in ONE bar (PEAK capacity) Components/ WBP_UniversalBar one reusable bar (parent: UUniversalBarWidget) WBP_BarHealth combined-capacity variant WBP_BarStamina stamina variant WBP_HUD_InGame ready HUD: health + stamina + status chips Theme/ put DA_UniversalBars_* theme assets here C++ (module UniversalBars): UUniversalBarWidget one animated bar UUniversalHUDWidget HUD container with high-level stat setters UUniversalBarsSubsystem global access point (UWorldSubsystem) UUniversalBarsTheme palette / geometry / chip-colour DataAsset ``` --- ## 3. Quick start ### Blueprint — easiest path (global API, no widget reference) 1. On `BeginPlay` (player controller / HUD), call `Universal Bars Subsystem → Create HUD` with `HUD Class = WBP_HUD_InGame`. 2. From **anywhere** in BP: ``` Get World Subsystem (UniversalBarsSubsystem) → Set Health (0.62) // 0..1, animates + flashes automatically → Set Stamina (0.8) → Set Hunger (0.16) // penalty zone eats into max HP (combined bar) → Set Weight (0.12) → Damage Health (0.2) // red flash + instant drop + lag tail → Heal Health (0.25) // green flash + smooth rise ``` Direction is detected for you: a decrease plays the damage animation, an increase plays the heal animation. ### C++ ```cpp #include "UniversalBarsSubsystem.h" if (UUniversalBarsSubsystem* Bars = UUniversalBarsSubsystem::Get(this)) { Bars->SetHealth(0.62f); Bars->SetHunger(0.16f); Bars->DamageHealth(0.2f); } ``` ### Driving a single bar directly Place a `WBP_UniversalBar` (or a preset variant) anywhere and call: ```cpp UUniversalBarWidget* Bar = ...; Bar->SetFillPercent(0.5f); // animated Bar->SetShieldPercent(0.25f); Bar->SetSegmentCount(10); // boss segments Bar->SetPenaltyZone("Hunger", 0.16f, FLinearColor(0.9f,0.6f,0.2f,1)); // animated zone Bar->PlayDamageFlash(); // manual flash ``` --- ## 4. Animation model (same as the HTML prototype) | Change | Bright fill | Lag tail | Flash | |---|---|---|---| | **Decrease / damage** | snaps down instantly | holds `DelayedDelay`s, then drains at `DelayedFallSpeed` | red (`DamageFlashColor`) | | **Increase / heal** | eases up at `FillRiseSpeed` | jumps to target (lighter "incoming" band) | green (`HealFlashColor`) | | **value < `LowThreshold`** | — | — | border pulses (low-value warning) | | **penalty zone change** | — | zone width eases at `ZoneInterpSpeed` | — | All tuning fields live on `UUniversalBarWidget` (Bar|Anim category). Set `bAutoFlashOnChange=false` to drive flashes manually. Under the hood the material exposes `FillPercent`, `DelayedFillPercent`, `FlashAmount`, `LowHPPulseAmount` — the widget tweens these every tick via a Dynamic Material Instance. --- ## 5. Combined "capacity" bar (PEAK) One bar = current value (bright) + depleted-but-recoverable zone (dark) + striped penalty zones eating max from the right: - `MaxFillPercent` — right edge of the usable region (`1 - sum(penalties)`). - `PenaltyCount` + `PenaltyEnd1..4` + `PenaltyColor1..4` — up to 4 striped zones. You never set these by hand — `SetHunger / SetWeight / SetCold` (HUD) or `SetPenaltyZone(Id, Width, Color)` (bar) manage them and animate the widths. Set a penalty to `0` to retract its zone. `PenaltyCount = 0` → the same material is a plain solo bar. --- ## 6. Material parameter reference **Scalars:** `FillPercent`, `DelayedFillPercent`, `ShieldPercent`, `MaxFillPercent`, `PenaltyCount`, `PenaltyEnd1..4`, `BarOpacity`, `BackgroundOpacity`, `CornerRadius`, `BorderSize`, `InnerPadding`, `EdgeSoftness`, `BarAspect`, `FlashAmount`, `LowHPPulseAmount`, `PulseSpeed`, `StripeAmount`, `StripeScale`, `StripeSpeed`, `SegmentCount`, `SegmentDividerSize`, `SegmentDividerOpacity`, `UseVerticalFill`, `InvertFill`, `NoiseAmount`, `TimeOffset`. **Vectors:** `FillColor`, `DelayedFillColor`, `ShieldColor`, `BackgroundColor`, `BorderColor`, `EmptyColor`, `FlashColor`, `StripeColorA`, `StripeColorB`, `PenaltyColor1..4`. `BarAspect` must roughly match the on-screen width/height ratio so the rounded corners stay circular (default 8 ≈ a 600×75 bar). --- ## 7. Theme `UUniversalBarsTheme` (DataAsset) centralises palette + geometry + chip colours. Create one under `/UniversalBars/Theme/` (right-click → Miscellaneous → Data Asset → Universal Bars Theme), then assign it to `WBP_HUD_InGame`'s `Theme` property. `UUniversalHUDWidget::ApplyTheme()` runs on construct and retints both bars and all chips. Per-preset look still lives in the `MI_UI_Bar_*` instances; the theme is the HUD-level override. --- ## 8. Presets (recommended values) | Preset | Fill | Notes | |---|---|---| | Health | `(0.30,0.85,0.20)` | white border, low-HP pulse, damage lag | | Stamina | `(0.85,0.95,0.30)` | thinner, no pulse | | Injury | `(0.75,0.20,0.20)` + `StripeAmount=1` | striped "broken" HP | | Shield | `(0.30,0.70,1.0)` + `ShieldPercent` | blue + overlay | | Boss | `(0.85,0.15,0.15)` + `SegmentCount=10` | wide, segmented, less rounded | | PeakCombined | green + Hunger/Weight penalties | one-bar HP+hunger+weight | Keep `BorderColor` pure white and `BorderSize` 0.06–0.10 for the toy/cartoon look; `CornerRadius` 0.5–0.7 for horizontal bars. --- ## 9. Demo / study mode (WBP_HUD_InGame) `WBP_HUD_InGame` ships with **Demo Mode ON** (`UUniversalHUDWidget::bDemoMode`). While on, the HUD's `NativeTick` runs a 10-step cycle every `DemoStepInterval` (1.6 s) so you can watch every animation live in PIE: ``` 0 DamageHealth(0.25) red flash + instant drop + lag tail 1 SetStamina(0.30) stamina drop 2 HealHealth(0.20) green flash + smooth rise 3 SetHunger(0.18) amber zone eases in from the right 4 SetWeight(0.14) red zone eases in 5 SetStamina(0.95) stamina refill 6 HealHealth(0.30) 7 SetHunger(0.0) hunger zone retracts 8 SetWeight(0.0) weight zone retracts 9 DamageHealth(0.45) big hit -> low-HP border pulse ``` To watch: add the HUD (`Subsystem → Create HUD`, or just drop it in any widget / PIE) and press Play. The cycle restarts each time the widget constructs. **Turn it off for shipping:** open `WBP_HUD_InGame` → Class Defaults → uncheck **Demo Mode**, or call `SetDemoMode(false)`. Read `DemoStepNow()` in `UniversalHUDWidget.cpp` to see exactly which API call drives each animation. ## 9b. Status chips (PEAK markers) In `WBP_HUD_InGame` the chips live in a `CanvasPanel` (`ChipCanvas`) **overlaid on the health bar**, not in a row below it. Each tick `UUniversalHUDWidget::PositionChips()` slides them to sit just above the centre of their zone, using `UUniversalBarWidget::GetUsableEnd()` / `GetZoneCenter("Hunger"|"Weight"|"Cold")`: - `ChipHeart` → the usable-HP / penalty boundary - `ChipHunger` → centre of the hunger zone (hidden until `SetHunger > 0`) - `ChipWeight` → centre of the weight zone - `ChipCold` → centre of the cold zone So when hunger/weight grow or shrink, the chips ride along with the zone edges. Add your own marker by placing an `Image` in `ChipCanvas` and binding it (or extend `PositionChips`). Swap the placeholder tints for real icon textures. ## 10. Notes / limits - The bar is a UI-domain material — it only renders inside UMG/Slate (not on meshes). Verify visuals in the UMG designer or content-browser thumbnail. - Up to 4 penalty zones are drawn by the material in a single draw call; the widget warns if you push more. - `SetFillPercent` clamps to 0..1. Feed it `CurrentHP / MaxHP`, etc.