How to make a sound play without it playing all at once?

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)

I sorta need the renderstepped for the tweening, so that’s why I used two instances for it

edit: nevermind I figured it out

TweenService exists for that reason pal.

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.