Custom Health/Resource Bar

Is there a way to create a custom health/resource bar in LUA?

The basic idea is:

local function CreateBar(name, previous) -- Create StatusBar with a text overlay
	local f = CreateFrame("StatusBar", "Fizzle"..name, UIParent)
	f:SetSize(200, 30)
	if not previous then
		f:SetPoint("LEfT", 10, 0)
	else
		f:SetPoint("TOP", previous, "BOTTOM")
	end
	f:SetStatusBarTexture("Interface\\TargetingFrame\\UI-StatusBar")
	f.Text = f:CreateFontString()
	f.Text:SetFontObject(GameFontNormal)
	f.Text:SetPoint("CENTER")
	f.Text:SetJustifyH("CENTER")
	f.Text:SetJustifyV("CENTER")
	return f
end

local function UpdateHealth(self, unit) -- Update the health bar
	local health = UnitHealth(unit)
	self:SetValue(health)
	self.Text:SetText(FormatLargeNumber(health) .. "/" .. FormatLargeNumber(self.healthMax))
end
local function UpdatePower(self, unit) -- Update the power bar
	local power = UnitPower(unit)
	self:SetValue(power)
	self.Text:SetText(FormatLargeNumber(power) .. "/" .. FormatLargeNumber(self.powerMax))
end
local function UpdateHealthMax(self, unit) -- Update min./max. health values
	self.healthMax = UnitHealthMax(unit)
	self:SetMinMaxValues(0, self.healthMax)
	UpdateHealth(self, unit)
end
local function UpdatePowerMax(self, unit) -- Update min./max. power values
	self.powerMax = UnitPowerMax(unit)
	self:SetMinMaxValues(0, self.powerMax)
	UpdatePower(self, unit)
end
local HealthBar = CreateBar("PayerHealth") -- Create the health bar
HealthBar:SetStatusBarColor(0, 1, 0) -- make it green
local PowerBar = CreateBar("PayerPower", HealthBar) -- Create the power bar (set to anchor below Health)
PowerBar:SetStatusBarColor(0, 0, 1) -- make it blue
HealthBar:SetScript("OnEvent", function(self, event, ...)
	local unit = ... -- For events starting with UNIT_ the first parameter is the unit
	if unit ~= "player" then  -- We"re only updating the player status ATM
		return -- So ignore any other unit
	end
	if event == "UNIT_HEALTH_FREQUENT" then -- Fired when health changes
		UpdateHealth(self, unit)
	elseif event == "UNIT_POWER_FREQUENT" then -- Fired when power changes
		UpdatePower(PowerBar, unit)
	elseif event == "UNIT_MAXHEALTH" then -- Fired when max. health changes
		UpdateHealthMax(self, unit)
	elseif event == "UNIT_MAXPOWER" then -- Fired when max. power changes
		UpdatePowerMax(PowerBar, unit)
	end
end)
UpdateHealthMax(HealthBar, "player") -- initialise the health bar for Player health
UpdatePowerMax(PowerBar, "player") -- initialise the power bar for Player power
HealthBar:RegisterEvent("UNIT_HEALTH") -- register the events to be used (UNIT_HEALTH_FREQUENT only exists in old versions these days
HealthBar:RegisterEvent("UNIT_POWER_FREQUENT") -- Health bar is handling events for both bars
HealthBar:RegisterEvent("UNIT_MAXHEALTH")
HealthBar:RegisterEvent("UNIT_MAXPOWER")

UNIT_HEALTH_FREQUENT changed to just UNIT_HEALTH in Shadowlands but remains the same in Classic and Classic TBC (for now???) Change to suit your needs if you get errors about events not being valid.

Other event/function names etc. may change over time but the basic ideas should remain the same

You could change bar:RegisterEvent(event) to bar:RegisterUnitEvent(event, “player”) if you were only interested in a specific unit (“player” in this case). This would mean you could get rid of the unit check in the OnEvent script. The code here is very generic.

3 Likes

Yea it’s simple and easy to understand. Just local function UpdateHealth(self)
self:SetValue(UnitHealth(“player”))
end
local function UpdatePower(self)
self:SetValue(UnitPower(“player”))
end
local Health = CreateFrame(“StatusBar”, “FizzleHealth”, UIParent)
Health:SetSize(200, 30)
Health:SetPoint(“LEfT”, 10, 0)
Health:SetStatusBarTexture(“Interface\TargetingFrame\UI-StatusBar”)
Health:SetMinMaxValues(0, UnitHealthMax(“player”))
local Power = CreateFrame(“StatusBar”, “FizzlePower”, UIParent)
Power:SetSize(Health:GetSize())
Power:SetPoint(“TOP”, Health, “BOTTOM”)
Power:SetStatusBarTexture(“Interface\TargetingFrame\UI-StatusBar”)
Power:SetMinMaxValues(0, UnitPowerMax(“player”))
Health:SetScript(“OnEvent”, function(self, event, …)
if event == “UNIT_HEALTH_FREQUENT” then
UpdateHealth(Health)
elseif event == “UNIT_POWER_FREQUENT” then
UpdatePower(Power)
elseif event == “UNIT_MAXHEALTH” then
Health:SetMinMaxValues(0, UnitHealthMax(“player”))
elseif event == “UNIT_MAXPOWER” then
Power:SetMinMaxValues(0, UnitPowerMax(“player”))
end
end)
UpdateHealth(Health)
UpdatePower(Power)
Health:RegisterEvent(“UNIT_HEALTH_FREQUENT”)
Health:RegisterEvent(“UNIT_POWER_FREQUENT”)
Health:RegisterEvent(“UNIT_MAXHEALTH”)
Health:RegisterEvent(“UNIT_MAXPOWER”)

Thank you! Is there a way to print text onto this?

I posted a basic bar using a build in statusbar widget. You can use what you like and add any elements you want to it like Fontstrings etc. and update them at the same time.

I’ll look into all that. Thanks for the help!

Updated the original to add some text and comments for future travelers.

5 Likes

All I want after coming back to the game after 6 years, is to reduce the size or make transparent the status text that covers the healthbar, it covers the player portrait the party healthbars, my targets healthbar, I can barely see the green bar behind because the text takes up 90% of the bar it used to be alot smaller and be toggleable for yourself only, plese help, I have no idea what to do with that code or where to paste it, please help.