It’s actually pretty simple. In your code, you used a forever loop with a wait() in between each loop. So let’s simulate the situation:
Frame 1: Health is full, so turn off the visual effects.
Frame 2: Health is still full, turn off the visual effects again.
Frame 3: Now the health is 30, so turn on the visual effects and start the tween.
Frame 4: The health is still at 30, turn on the visual effects and start another tween.
Frame 5: The health is still at 30, turn on the visual effects and start another tween.
So you get the idea. Because you check the health every single loop, with only a wait() in between, the tween is constantly starting over and over, so the server is probably really confused. I don’t know what behavior will be produced, would the new tween override the old tween? Or would they balance each other out? I don’t know. I would suggest connecting this instead to an event, which would not only solve this problem, but also make it easier on the server. Like this:
script.Parent.Humanoid:GetPropertyChangedSignal("Health"):Connect(function()
if script.Parent.Humanoid.Health <= 40 then
game.Lighting.ColorCorrection.Enabled = true
game.Lighting.Blur.Enabled = true
player3.heart.Enabled = true
tween1:Play()
tween2:Play()
tween3:Play()
tween4:Play()
else
game.Lighting.ColorCorrection.Enabled = false
game.Lighting.Blur.Enabled = false
player3.heart.Enabled = false
end
end
Or if you want the tween to occur repeatedly while the player is at low health:
script.Parent.Humanoid:GetPropertyChangedSignal("Health"):Connect(function() -- Only calls the function when the player's health value changes
if script.Parent.Humanoid.Health <= 40 then
game.Lighting.ColorCorrection.Enabled = true
game.Lighting.Blur.Enabled = true
player3.heart.Enabled = true
while script.Parent.Humanoid.Health <= 40 do -- Visual effect repeats as long as the player is in low health
tween1:Play()
tween2:Play()
tween3:Play()
tween4:Play()
tween1.Completed:Wait() -- You could change this to something like wait(1) or some other number depending on how often you want the effect to loop
tween8.Completed:Wait() -- You could change this to something like wait(1) or some other number depending on how often you want the effect to loop
end
else
game.Lighting.ColorCorrection.Enabled = false
game.Lighting.Blur.Enabled = false
player3.heart.Enabled = false
end
end
Also, about your problem with keeping the heart in the center. There’s only one fact you need to know. Roblox’s GUI objects’ positions are based on their top left corners, which means that if you want to do something like centering the heart, you probably need to do some calculation like:
local midX = 0.5
local midY = 0.5
heart.Position = UDim2.new(midX - heart.Size.X.Scale / 2, 0, midY - heart.Size.Y.Scale / 2, 0)
But you could change this to Offset instead of Scale depending on how your GUI is formatted. Basically just subtract half the GUI’s size from the center position.
I hope this helps solve your problem!