HUD
Build heads-up displays with health bars, minimaps, and score tracking.
Introduction
HUDs display critical game information. This guide covers health bars, minimaps, score displays, damage numbers, and notification systems.
Guide 23 of 25
Screenshot
Step-by-Step Guide
Design the HUD layout
Plan HUD elements: health bar (bottom-left), minimap (top-right), score (top-center), ability icons (bottom-center).
Create health bars
Build a bar with background and fill image. Update fill scale based on health percentage. Add color transitions.
Add a minimap
Create a small canvas (200x200) top-right. Render icons for player (center), enemies (red), objectives (yellow).
Display score and stats
Show score, level, XP bar, ammo count. Update text elements via UI API. Use right-aligned text.
Add damage numbers
Spawn floating text at hit positions. Animate upward with fade-out over 1 second. Pool text objects.
Create notifications
Show toast notifications for events (item collected, quest update). Slide in from top, auto-dismiss after 3s.
FluxScript Example
Here is a complete FluxScript implementation for this guide:
on start {
ui.show("hud")
ui.setBar("healthBar", 1.0)
ui.setBar("shieldBar", 1.0)
ui.setBar("xpBar", 0.0)
ui.setText("scoreText", "Score: 0")
minimap = ui.getElement("minimap")
minimap.setRange(50)
minimap.addIcon("player", player, { color: color(0,255,0), size: 4 })
enemies = world.findAll("enemy")
for i = 0 to enemies.length {
minimap.addIcon("enemy_" + i, enemies[i], { color: color(255,0,0), size: 3 })
}
}
on update(dt) {
healthPercent = player.health / player.maxHealth
ui.setBar("healthBar", healthPercent)
if healthPercent > 0.5 {
ui.setBarColor("healthBar", color(0, 220, 80))
} else if healthPercent > 0.25 {
ui.setBarColor("healthBar", color(220, 200, 0))
} else {
ui.setBarColor("healthBar", color(220, 50, 50))
}
shieldPercent = player.shield / player.maxShield
ui.setBar("shieldBar", shieldPercent)
ui.setText("scoreText", "Score: " + score)
minimap.update()
}
on event("tookDamage", data) {
ui.spawnFloatingText({
position: data.target.position + vec3(0, 2, 0),
text: "-" + math.round(data.amount),
color: data.type == "critical" ? color(255,50,50) : color(255,200,50),
fontSize: data.type == "critical" ? 24 : 16,
lifetime: 1.0, velocity: vec3(0, 3, 0), fadeOut: true
})
}
on event("playerDamaged", data) {
ui.flash("damageVignette", 0.3)
if data.source != null {
dir = math.normalize(data.source.position - player.position)
ui.showDirectionIndicator(math.atan2(dir.x, dir.z), 0.5)
}
}
func showNotification(text, type) {
colors = { info: color(100,180,255), success: color(80,220,100), warning: color(255,200,50), error: color(255,80,80) }
ui.addNotification({ text: text, color: colors[type] || colors.info, autoDismiss: 3.0, fadeOut: 0.5 })
}Node Graph Example
Prefer visual programming? Here is the equivalent Node Graph:
[On Start] --> [Show: HUD] --> [Init: bars, score, minimap]
[On Update] --> [Set: healthBar % + color (green/yellow/red)]
--> [Set: shieldBar, scoreText]
--> [Update: minimap]
[On Event "tookDamage"] --> [Spawn: floating damage text]
--> [Set: color (red=crit, yellow=normal)]
--> [Animate: up + fade out, 1s]
[On Event "playerDamaged"] --> [Flash: red vignette]
--> [Show: direction indicator]
[Function: showNotification] --> [Add: notification toast]
--> [Auto-dismiss 3s]Optimization Tips
Keep your implementation fast and efficient with these optimization tips:
- Update HUD only when values change. Do not set text/bars every frame if values have not changed. Compare and skip.
- Pool damage number text objects. Spawning and destroying text per hit causes GC spikes. Pre-create 20 and recycle.
- Use anchored positioning for HUD elements. Health bar bottom-left, minimap top-right. Anchors adapt to screen sizes.
- Limit minimap update frequency. Updating minimap icons every frame is expensive. Update every 3-5 frames.
Common Mistakes
Updating every HUD element every frame
Only update elements when values change. Reduces significant CPU.
Damage numbers not pooled
Spawning text per hit causes GC spikes with rapid-fire weapons. Pre-pool 20-30 text objects.
