How to make a freefall sound that keeps getting louder?

Hey there, i need help to make a freefall script…


I want to achieve this:

a Freefall sound that keeps getting louder as longer you fall

(the original video here)


(Many thanks to Punish who made the video)

My questions are:


  • How can i make a script for the freefall sound
  • How can i make a sound play when the player drops on the floor after the freefall
  • How can i make a effect for the freefall

7 Likes

You could lets say the amount of the time that you are falling.

And just for that time adjust the sound volume over 0.25

would be something like this i believe:

local sound =  sound
for i =10, 0, -1 do 
task.wait(1)
sound.Volume += 0.25
end

Not entirely sure that this works it’s just not time for me right now.

3 Likes

thats ok…im happy with every help i get!

3 Likes

The easy way to go about this is to use a .Magnitude check.

Make a separate script for the handling of the sound that runs a while ... do loop.
Get the .Position of the player twice with a set amount of time in between.

For example:

while true do
	local playerPos1 = character.HumanoidRootPart.Position
	task.wait(0.1)
	local playerPos2 =  character.HumanoidRootPart.Position
	
	if (playerPos1 - playerPos2).Magnitude >= 10 then --//Set the number to the magnitude you want the sound to start playing
		--//Handle the sound volume
	end
	
end

Then if the .Magnitude reached over a specific amount, you can do some maths to determine how loud the sound will get dependent on how large the magnitude is.

Note: the smaller the task.wait time is, the more accurate it will be.

1 Like

I’m not sure how efficient is this for long term side. As this may cause memory leaks etc.

I think it would be better to make functions after a check point(a part touch) that will run to check if the player is falling etc. Your code is a bit different from what the OP asked…

I think if we put our brains together we can find the best way for this.

2 Likes

Okay @MRX_perte I think i got this:

I do have a plan ill try to recreate it as i can’t think on devfourm ill create a basic system that you can modify to your liking and someone else can maybe add some stuff to correct me if i am wrong.

3 Likes

As mentioned, it’s an easy script I was able to think up in a few seconds. It may not be efficient nor long-term, but it can at least harvest ideas for the OP to develop further with.

So far I know, LuaU is a garbage collecting script, so when the variables get replaced, there will be no pointer towards those values, so they are scrapped as soon as they are replaced. No memory leak. If you want to be sure, you can always make the variables before the loop like so:

local playerPos1
local playerPos2

while true do
	playerPos1 = character.HumanoidRootPart.Position
	task.wait(0.1)
	playerPos2 =  character.HumanoidRootPart.Position
	
	if (playerPos1 - playerPos2).Magnitude >= 10 then --//Set the number to the magnitude you want the sound to start playing
		--//Handle the sound volume
	end
	
end

Seeing the title, description and video attached, I get the impression OP is after a way to play a sound dependent on how fast the player is falling. Longer fall = Faster speed = Louder sound. With .Magnitude of the first and last position of a player is accurate to depict when they fall and how fast they fall.


As for your .Touched suggestion, it’s a big workaround and takes a lot of maintenance to apply it to every situation where the player can possibly fall in the map. A single script working in the background to run a constant check based on the player position is therefore a lot more flexible and can be applied in every situation. If you want to optimise it as much as possible, you can use the .Touched boundary to disable and enable the script where necessary, so it only runs when it should be used.

4 Likes

i tryed making a code myself (i know its way to complicated)… but the sound keeps playing loud even when you jump

-- Insert the sound ID of the freefall sound you want to use
local soundId = "rbxassetid://3308152153"

-- Minimum and maximum falling speeds
local minSpeed = 0 -- Change this as per your requirement
local maxSpeed = 1000 -- Change this as per your requirement

-- Create a LocalScript in StarterPlayerScripts and add this code

-- Get the character and humanoid of the player
local player = game.Players.LocalPlayer
local character = player.Character or player.CharacterAdded:Wait()
local humanoid = character:WaitForChild("Humanoid")

-- Load the sound
local sound = Instance.new("Sound")
sound.SoundId = soundId
sound.Parent = workspace

-- Function to update the sound volume based on falling speed
local function updateSound()
	local speed = humanoid:FindFirstChild("RootPart").Velocity.Y
	local volume = (speed - minSpeed) / (maxSpeed - minSpeed)
	volume = math.clamp(volume, 0, 0.1) -- Ensuring volume value stays between 0 and 1
	sound.Volume = volume
end

-- Trigger the updateSound function as long as the player is falling
humanoid.FreeFalling:Connect(function(isFreeFalling)
	if isFreeFalling then
		sound:Play()
		humanoid:MoveTo(character.HumanoidRootPart.Position)
		humanoid.MoveToFinished:Wait()
	else
		sound:Stop()
	end
end)

-- Continuously update the sound volume while the player is falling
humanoid:GetPropertyChangedSignal("FreeFalling"):Connect(function()
	if humanoid.FreeFalling then
		updateSound()
	end
end)

(local script = StarterPlayerScripts)

2 Likes

robloxapp-20240131-2048500.wmv

1 Like

Sorry for the late response.

So it would be something like a time for parkour but not really.

local StartPart = workspace.Model.Start
local EndPart = workspace.Model.End

local Sound = script.Parent.Sound
local SoundStarted = false

StartPart.Touched:Connect(function()
	if SoundStarted == false then
		SoundStarted = true
		print("start")
		Sound:Play()

		for i = 20, 0, -1 do
			task.wait(1)
			if SoundStarted == true then
				Sound.Volume += 0.25
			end
		end
	end
end)

EndPart.Touched:Connect(function()
	if SoundStarted == true then
		Sound:Stop()
		Sound.Volume = 1
		SoundStarted = false
		print("stop")
	end
end)

I did test it you can change stuff of course and good luck with your game DON’T GIVE UP!

So Start part would be the part where is the hole or what you have there and the end part would be before landing on the ground.

I want to see a finished game someday :star_struck:

3 Likes

(And @aabols2010)

Why not check to see if the player’s state has changed to freefall?
When that happens fire a loop that runs every .1 or .2 seconds and read the Player’s speed. Multiply the sound volume by a percentage of the speed value until the player is no longer freefalling.
This will give you a constant increase in the sound value and you can change how much the sound increases by the percentage value.
It’s probably a good idea to clamp the volume so you don’t blow out player’s eardrums.

3 Likes

i tryed it and it dident work for me… ima look into this tomorrow agian

3 Likes

Well then you can check until it’s like 5-7. Depending how long are you falling you can adjust the 20 seconds to what ever. This was just a sketch as the players state didn’t work for him.

I wouldn’t say that I’m the best coder. Everyone learns new things every day.

This is what i know/i have learnt. I do understand i don’t want to give a bad example.

3 Likes

idk what i did wrong… it still dosent work for me…

2 Likes

Any errors?

Are you sure that you changed the stuff in the local variables where they are for you?

I’ll check my code once again in a minute.

1 Like

Now I actually had some free time, I decided I wanted to find a solution for this.


I made it somewhat more efficient than my last suggestion, whereas my last script ran a continuous while .. do loop, the new script only runs a loop if the StateType of the Humanoid is equals to Freefall.

Not the most optimized, but I tried. Here is the code with a video preview.


LocalScript located in StarterPlayer → StarterCharacterScripts

local character = script.Parent
local windSound = script.wind_loop_02 --//Sound of your choice. This one is used in the video

local humanoidRootPart = character:WaitForChild("HumanoidRootPart")
local humanoid = character.Humanoid
local hrpVelocity
local soundVelocity

windSound.Looped = true
windSound.Volume = 0
windSound:Play()

humanoid.StateChanged:Connect(function(oldState, newState)
	
	if newState == Enum.HumanoidStateType.Landed then
		windSound.Volume = 0
		--//print("Landed.") - debugging
	elseif newState == Enum.HumanoidStateType.Freefall then
		
		while newState == Enum.HumanoidStateType.Freefall do
			hrpVelocity = humanoidRootPart.Velocity.Y
			
			if hrpVelocity <= 0 then
				soundVelocity = math.abs(hrpVelocity)
				
				if soundVelocity >= 75 then
					windSound.Volume = (soundVelocity - 75) / 100
					--//print(windSound.Volume) - debugging
				end
				
			end
			task.wait(0.05)
		end
		
	end
	
	windSound.Volume = 0
	--//print("End fall.") - debugging
	
end)

3 Likes

It worked perfect for me…
but i changed some things for my game…

local character = script.Parent
local windSound = script.wind_loop_02 --//Sound of your choice. This one is used in the video

local humanoidRootPart = character:WaitForChild("HumanoidRootPart")
local humanoid = character.Humanoid
local hrpVelocity
local soundVelocity
local currentVolume = 0
local targetVolume = 0
local minPlaybackSpeed = 0.5 -- Minimum playback speed of the sound
local maxPlaybackSpeed = 2 -- Maximum playback speed of the sound

windSound.Looped = true
windSound.Volume = 0
windSound:Play()

function updateSound()
	local playbackSpeed = minPlaybackSpeed + (maxPlaybackSpeed - minPlaybackSpeed) * currentVolume
	windSound.Volume = currentVolume * (0.0001 - humanoidRootPart.Velocity.Y / 700)
	windSound.PlaybackSpeed = playbackSpeed
end

humanoid.StateChanged:Connect(function(oldState, newState)
	if newState == Enum.HumanoidStateType.Landed then
		targetVolume = 0
		--//print("Landed.") - debugging
	elseif newState == Enum.HumanoidStateType.Freefall then
		targetVolume = 1
	end
end)

game:GetService("RunService").Heartbeat:Connect(function()
	currentVolume = currentVolume + (targetVolume - currentVolume) * 0.0005
	updateSound()
end)

hanks for the help

Best regards, MRX_perte

1 Like

wait the script dosent work anymore

it says:

wind_loop_02 is not a valid member of LocalScript “Workspace.MRX_perte.LocalScript” - Client - LocalScript:2
Stack Begin - Studio
Script ‘Workspace.MRX_perte.LocalScript’, Line 2 - Studio - LocalScript:2
Stack End

but the wind_loop_02 is in the local script
image

what im i doing wrong???

1 Like

local windSound = character:WaitForChild("wind_loop_02")

i tryed waitforchild but now i get this error:

Infinite yield possible on ‘Workspace.MRX_perte:WaitForChild(“wind_loop_02”)’ - Studio
Stack Begin - Studio
Script ‘Workspace.MRX_perte.LocalScript’, Line 2 - Studio - LocalScript:2
Stack End

1 Like
local character = script.Parent
local windSound = game.Workspace:FindFirstChild("wind_loop_02")

local humanoidRootPart = character:WaitForChild("HumanoidRootPart")
local humanoid = character.Humanoid
local hrpVelocity
local soundVelocity
local currentVolume = 0
local targetVolume = 0
local minPlaybackSpeed = 0.5 -- Minimum playback speed of the sound
local maxPlaybackSpeed = 2 -- Maximum playback speed of the sound

if windSound then
	windSound.Looped = true
	windSound.Volume = 0
	windSound:Play()
else
	error("Sound 'wind_loop_02' not found in character hierarchy.")
end

function updateSound()
	local playbackSpeed = minPlaybackSpeed + (maxPlaybackSpeed - minPlaybackSpeed) * currentVolume
	windSound.Volume = currentVolume * (0.0001 - humanoidRootPart.Velocity.Y / 700)
	windSound.PlaybackSpeed = playbackSpeed
end

humanoid.StateChanged:Connect(function(oldState, newState)
	if newState == Enum.HumanoidStateType.Landed then
		targetVolume = 0
		--//print("Landed.") - debugging
	elseif newState == Enum.HumanoidStateType.Freefall then
		targetVolume = 1
	end
end)

game:GetService("RunService").Heartbeat:Connect(function()
	currentVolume = currentVolume + (targetVolume - currentVolume) * 0.0005
	updateSound()
end)

fixed it!

1 Like