I wanted to make this sound called LowHealth play whenever the player’s HP is considered in the “red”. I put it line 22, but it just loops the sound endlessly. How would I make it play properly without it playing all at once, over and over again?
repeat wait() until game:GetService("Players").LocalPlayer.Character ~= nil
local Player = game:GetService("Players").LocalPlayer
local Character = Player.Character
local Humanoid = Character.Humanoid
local Gui = script.Parent
local LowHealth = Gui:WaitForChild("LowHealth")
local Green = Humanoid.MaxHealth / 2
local Red = Humanoid.MaxHealth / 4
game:GetService('RunService').RenderStepped:connect(function() -- bar code
Gui.HealthInfo.HealthBar:TweenSize(UDim2.new((Humanoid.Health / Humanoid.MaxHealth) * 0.85, 0, 0.3, 0), "Out", "Linear", 0.1, true)
if Humanoid.Health > Green then --green
Gui.HealthInfo.HealthBar.HealthImage.Image = ("http://www.roblox.com/asset/?id=12442263965")
end
if Humanoid.Health < Green then -- yellow
Gui.HealthInfo.HealthBar.HealthImage.Image = ("http://www.roblox.com/asset/?id=270195888")
end
if Humanoid.Health < Red then -- red
Gui.HealthInfo.HealthBar.HealthImage.Image = ("http://www.roblox.com/asset/?id=270195929")
--line 22
end
Gui.NameFrame.PlayerName.Text = ""..Player.Name..""
Gui.NameFrame.DisplayName.Text = "("..Player.DisplayName..")"
end)
local HealthText = Gui.HealthInfo.HealthText
local MaxHealthText = Gui.HealthInfo.MaxHealthText
local function ChangeHealth() -- number code
HealthText.Text = Humanoid.Health
MaxHealthText.Text = Humanoid.MaxHealth
end
ChangeHealth()
Humanoid.HealthChanged:Connect(ChangeHealth)
It’s obviously looping all over because you’re wrapping it in a RenderStepped event, which fires before every frame (if i recall correctly).
Let’s go through your code to see what we can fix here.
First, let’s declare services so we don’t have to write them again in the future:
local Players = game:GetService("Players")
Next, instead of doing:
repeat wait() until game:GetService("Players").LocalPlayer.Character ~= nil
You can use this line:
local Player = Players.LocalPlayer
-- Won't be nil, since scripts in StarterPlayer will always start executing after player joins.
local Character = Player.Character or Player.CharacterAdded:Wait()
-- It's the same thing, but better.
Now let’s get to your actual problem. We don’t need a RunService loop here, we can use the .HealthChanged event. You did exactly that, so why don’t we wrap all in there?
local Players = game:GetService("Players")
-- Your variables
local Player = Players.LocalPlayer
local Character = Player.Character or Player.CharacterAdded:Wait()
local Humanoid = Character:WaitForChild("Humanoid")
local Gui = script.Parent
local HealthInfo = Gui:WaitForChild("HealthInfo")
local HealthImage = HealthInfo:WaitForChild("HealthBar"):WaitForChild("HealthImage")
local LowHealth = Gui:WaitForChild("LowHealth")
local HealthText = Gui.HealthInfo.HealthText
local MaxHealthText = Gui.HealthInfo.MaxHealthText
local Sound -- Your sound
local Green = 50
local Red = 25
-- Some settings
Gui.NameFrame.PlayerName.Text = ""..Player.Name..""
Gui.NameFrame.DisplayName.Text = "("..Player.DisplayName..")"
local function onHealthChanged(health)
if health > Green then
HealthImage.Image = "rbxassetid://12442263965"
end
if health <= Green then
HealthImage.Image = "rbxassetid://270195888"
end
if health <= Red then
HealthImage.Image = "rbxassetid://270195929"
Sound:Play()
end
HealthText.Text = health
MaxHealthText.Text = Humanoid.MaxHealth
end
Humanoid.HealthChanged:Connect(function(health)
onHealthChanged(health)
end)