How would I go about scripting an odd-shaped health bar?

I know I can listen for player’s health changes to adjust the health thing, but how do I make the green bar change size?

4 Likes

Instead of tweening the size, you could try tweening a red ui over it so the green ui is under the red

Then what do I do? It looks like this.

Separate the green bar from the frame, then instead of changing size use UIGradient transparency and UIGradient offset on the green bar.
image
This is how the gradient should look like to make it work with offset:

2 Likes

Like this?

1 Like

Don’t use color but transparency:
image

9 Likes

You’re a legend, I didn’t even know about this! Thanks!

Thanks, you then simply move the offset to make it work:


3 Likes

Gotta say it works like charm!

1 Like

Genius! Thank you so much for sharing this trick!

2 Likes

how did you make the gradient move based off the amount of hp lost

2 Likes

Did you ever find out? Im stumped

That could be achieved by updating UIGradient.Offset to a new value based on the current percentage of Humanoid.Health divided by Humanoid.MaxHealth.

In this case, there’s an extra step that needs to be done before updating the Offset since a value of -1 is when the UIGradient is invisible and a value of 0 is when it’s still completely full, which would not work by default (because if a Character’s Humanoid has 0 health, which is equivalent to 0%, the gradient would not be affected since it only starts changing at values below 0, at least with how the solution for this post created the UIGradient).

Example:

local Players = game:GetService("Players")
local player = Players.LocalPlayer

local UIGradient = script.Parent

local connection
local function updateHealthBar(Humanoid, newHealth)
	
	local currentHealth = newHealth or Humanoid.Health
	local maximumHealth = Humanoid.MaxHealth
	local percentage = currentHealth / maximumHealth
	
	local emptyHealthbarOffset = -1 --[[
Update this to the Offset value where the UIGradient is fully invisible.
With how it was set up in this thread's solution,
-1 is when the gradient is no longer visible
--]]

	UIGradient.Offset = Vector2.new(-1 + percentage, -1 + percentage) --[[ 
Explanation for the goal Offset value: If Health is full, the percentage
will equal 1. Because the UIGradient does not
appear to decrease in size until its value is below 0, we added
the "emptyHealthbarOffset" and the percentage together to make sure it's
at the correct value
(e.g. -0.1 is equivalent to 90% Health and 90% of the Healthbar being visible,
-0.5 is equivalent to 50%, -0.75 is equivalent to 25%, and -1 is equivalent to 0%)
--]]
end

---

local function healthChangedConnection(Character)
	
	if connection == nil then
		local Humanoid = Character:WaitForChild("Humanoid")
		
		connection = Humanoid.HealthChanged:Connect(function(newHealth)
			updateHealthBar(Humanoid, newHealth)
		end)
	end
end

player.CharacterAdded:Connect(healthChangedConnection)

player.CharacterRemoving:Connect(function()
	if connection ~= nil then
		connection:Disconnect()
		connection = nil
	end
end)

if player.Character then
	healthChangedConnection(player.Character)
end

If you want the Healthbar to have a smooth transition when the Character’s Health updates, you can utilize the TweenService.

Example revision that uses TweenService:

local TweenService = game:GetService("TweenService")
local Players = game:GetService("Players")
local player = Players.LocalPlayer

local UIGradient = script.Parent

local healthbarTweenInfo = TweenInfo.new(
	0.2, -- Total time for the Healthbar to update
	Enum.EasingStyle.Sine, -- EasingStyle
	Enum.EasingDirection.Out -- EasingDirection
)


local connection
local function updateHealthBar(Humanoid, newHealth)
	
	local currentHealth = newHealth or Humanoid.Health
	local maximumHealth = Humanoid.MaxHealth
	local percentage = currentHealth / maximumHealth
	
	local emptyHealthbarOffset = -1 --[[
Update this to the Offset value where the UIGradient is fully invisible.
With how it was set up in this thread's solution,
-1 is when the gradient is no longer visible
--]]
	
	local healthbarTweenGoal = {
		Offset = Vector2.new(-1 + percentage, -1 + percentage)
	}
	
	local healthbarAnimation = TweenService:Create(UIGradient, healthbarTweenInfo, healthbarTweenGoal)
	healthbarAnimation:Play()
--[[ 
Explanation for the goal Offset value: If Health is full, the percentage
will equal 1. Because the UIGradient does not
appear to decrease in size until its value is below 0, we added
the "emptyHealthbarOffset" and the percentage together to make sure it's
at the correct value
(e.g. -0.1 is equivalent to 90% Health and 90% of the Healthbar being visible,
-0.5 is equivalent to 50%, -0.75 is equivalent to 25%, and -1 is equivalent to 0%)
--]]
end

---

local function healthChangedConnection(Character)
	
	if connection == nil then
		local Humanoid = Character:WaitForChild("Humanoid")
		
		connection = Humanoid.HealthChanged:Connect(function(newHealth)
			updateHealthBar(Humanoid, newHealth)
		end)
	end
end

player.CharacterAdded:Connect(healthChangedConnection)

player.CharacterRemoving:Connect(function()
	if connection ~= nil then
		connection:Disconnect()
		connection = nil
	end
end)

if player.Character then
	healthChangedConnection(player.Character)
end

Relevant Roblox Creator Documentation Site Resources