How would I tween the y-axis of the offset of a UI Gradient, to fit the players health

image
Basically im trying to make the image go transparent based off how much health there is left, example:
50 Health =
image

I literally just need someone who is good at math to make a formula.
Full Value = -0.15

Transparent Value = 0.99
(when i said full value that means the offset until its fully visible)
(when i said transparent value that means like the offset until its fully transparent)

this is like asking people to do homework lol.

I’m still surprised this isn’t in the math library yet, but this is a very common thing in game development you just use a map function https://rosettacode.org/wiki/Map_range

2 Likes

Can you give me a example, or like tell me what the lua equivulant is, im very confused on whats happening here, sorry.

Yo, I gotchu; copy my homework:

local TS = game:GetService("TweenService")

local gradient : UIGradient = ...

local function mapRange(a1, a2, b1, b2, s)
	return b1 + (s-a1)*(b2-b1)/(a2-a1)
end

local function OnHealthChanged(health, maxHealth)
	local minMap = -.15
	local maxMap = 0.99

	--// assuming health is x/100
	local newOffsetY = math.clamp(mapRange(0, 100, minMap, maxMap, health), minMap, maxMap)
	
	print(newOffsetY)

	TS:Create(
		gradient,
		TweenInfo.new(.1),
		{Offset = Vector2.new(gradient.Offset.X, newOffsetY)}
	):Play()
end

OnHealthChanged(100, 100)
OnHealthChanged(70, 100)
OnHealthChanged(50, 100)
OnHealthChanged(30, 100)
OnHealthChanged(0, 100)

Hope this helps! :smile:

Yooo bro thanks for the homework, although it does work until the player health gets under 50, it starts going up after that, like reversed.

That might be caused by the way your gradient is set up. I tested it with my own gradient and it had no problem at the 50 mark.

I used this code:

local TS = game:GetService("TweenService")

local gradient : UIGradient = script.Parent.UIGradient

local function mapRange(a1, a2, b1, b2, s)
	return b1 + (s-a1)*(b2-b1)/(a2-a1)
end

local function OnHealthChanged(health)
	local minMap = -.15
	local maxMap = 0.99

	--// assuming health is x/100
	local newOffsetY = math.clamp(mapRange(0, 100, minMap, maxMap, health), minMap, maxMap)

	print(newOffsetY)

	TS:Create(
		gradient,
		TweenInfo.new(.1),
		{Offset = Vector2.new(gradient.Offset.X, newOffsetY)}
	):Play()
end

for i = 100, 0, -1 do
	OnHealthChanged(i)
	task.wait(1/60)
end

And this gradient:

image
image
image

My gradient is rotated by exactly 90, and is set to -0.15 on offset y axis


When it starts it, inverts itself?
image
(this is at like 90 health)

I tested it with the same properties that you have, but mine is working fine? Could you share a snippet of the code that moves the gradient?

image

You can pass health in as a parameter in the HealthChanged function:

Character.Humanoid.HealthChanged:Connect(function(health)
	OnHealthChanged(health)
end)

You should initialize the character like this:

local Player = game.Players.LocalPlayer
local Character = Player.Character or Player.CharacterAdded:Wait()

It waits for the character to be added without making a repeat loop.


Also, you can remove maxHealth and the second argument of OnHealthChanged; we ended up not needing maxHealth for any calculations.

I don’t see any issues though, just things to optimize. Is the HealthGradient object rotated? And can you show the output?

1 Like

Object is not rotated, the UIGradient is rotated by 90.
fixed the rest, but it still inverts itself to go upwards.
Like when i set the players health to 90, it progresses backwards.
Like its at the 90 health position but inverted.
Before change to 90 health:
image
After change to 90 health:
image
When at 1 health:
image

Can you include a screenshot of the output so that I can see the print(newOffsetY)? Example:


(Ignore my goofy font)

image
90 health
50 health
1 health

Looks like the offset is working as it should (matches the working output), try messing around with the UIGradient rotation to see if that fixes it.

You may also need to change the initial offsetY to something else when rotating; if you do, make sure to update that in the minMap value inside the script.

Oh i want it in reverse sorry :skull:,should’ve probally said that.

It’s 3 am and this is so confusing wym :skull:

You want the health icon to fill as the player’s health goes down?

no to go down lol.
im very confused too on how this isnt working, everything looks fine but, its not working?
let me mess around with transparency


fixed it and it goes in reverse still.
im trying to make the value go from -1.5 to 0.9

try to doublecheck the maprange function and see if you did the math right

(p.s, my brain is actively melting…)

Math is working fine, it’s because the application of it was done wrong, try this:

local newOffsetY = maxMap - (math.clamp(mapRange(0, 100, minMap, maxMap, health), minMap, maxMap) + math.abs(minMap))
1 Like

YOU DID IT!!! YOU HELPED ME COMPLETE MY HOMEWORK!!! Thank you.

1 Like