I have been working on a little thing for a few weeks to a month now and I am not super skilled in scripting.
If you do not understand what I mean by the title, I mean as if each footstep audio is an individual audio, not a single track. For example, lets say we have 6 footstep noises. Every 0.5 seconds or so you walk, one of those sounds are randomly chosen to be played.
Here is a video that is kind of shows what I am going for.
If you pay close attention to the audio, some sounds are repeated, thus showing that the audios are randomly selected.
I would like it if someone could help me figure this out?
PS: I don’t really think this matters but I got the video off YouTube since my recording software is bugging out.
you can put a few sounds in a folder under the script, use the script to get the folder, then in a loop select a child from the folder randomly using something like local randomSound = folder:GetChildren[math.random(1, #folder:GetChildren)] and then using that you have your random sound. if you dont know how to play this sound or make a loop that would do this i would recommend learning more about scripting. TheDevKing on youtube has some really great tutorials that can help you learn how to script, by the way.
Instead of having lots of slightly different sounds, you could place a sound effect instance under the sound object to make the footsteps sound different. E.g. put a PitchShiftSoundEffect under the sound and change the octave value a little each time the sound is played.
This is easier to do than using lots of different sounds and also uses less memory
here’s my own footstep system that I use, it’s material based and you can get some inspo from it if you like. goes in StarterCharacterScripts.
local Players = game:GetService("Players")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local RunService = game:GetService("RunService")
local player = Players.LocalPlayer
local char = player.Character or player.CharacterAdded:Wait()
local humanoid = char:WaitForChild("Humanoid")
local hrp = char:WaitForChild("HumanoidRootPart")
local footstepFolder = script:WaitForChild("FootstepSounds")
-- Settings
local BASE_WALK_SPEED = 14
local BASE_STEP_INTERVAL = 0.4
local stepCooldown = 0
-- Function to get interval based on current walk speed
local function getStepInterval()
local speed = humanoid.WalkSpeed
if speed <= 0 then return BASE_STEP_INTERVAL end
return BASE_STEP_INTERVAL * (BASE_WALK_SPEED / speed)
end
local function trim(str)
return (str:gsub("^%s*(.-)%s*$", "%1"))
end
-- Play a random sound for a given material
local function playFootstep(material)
local matFolder = nil
local materialName = material.Name:lower() -- lowercase for comparison
-- Search all folders to find one whose name list contains this material
for _, folder in ipairs(footstepFolder:GetChildren()) do
if folder:IsA("Folder") then
local names = string.split(folder.Name, "/")
for _, name in ipairs(names) do
if trim(name):lower() == materialName then
matFolder = folder
break
end
end
if matFolder then break end
end
end
if not matFolder then matFolder = footstepFolder["Plastic/SmoothPlastic"] end
local sounds = matFolder:GetChildren()
if #sounds == 0 then return end
local chosen = sounds[math.random(1, #sounds)]:Clone()
chosen.Parent = hrp
chosen.RollOffMaxDistance = 50
chosen.Volume = 0.2
chosen:Play()
game.Debris:AddItem(chosen, chosen.TimeLength + 0.1)
end
-- Detect footsteps
RunService.RenderStepped:Connect(function(dt)
if humanoid.MoveDirection.Magnitude > 0 and humanoid:GetState() == Enum.HumanoidStateType.Running then
stepCooldown -= dt
if stepCooldown <= 0 then
local rayOrigin = hrp.Position
local rayDirection = Vector3.new(0, -5, 0)
local params = RaycastParams.new()
params.FilterDescendantsInstances = {char}
params.FilterType = Enum.RaycastFilterType.Exclude
local result = workspace:Raycast(rayOrigin, rayDirection, params)
if result and result.Material then
playFootstep(result.Material)
end
stepCooldown = getStepInterval()
end
else
stepCooldown = 0
end
end)
My friends who are advanced in programming were able to help me with this problem, so here’s the scripts we used and what is required.
Remote Event titled “Footstep” in ReplicatedStorage
Default Script in ServerScriptStorage
local footstepsFolder = game.SoundService:WaitForChild("your audio folder here")
local RS = game:GetService("ReplicatedStorage")
local FSevent = RS:WaitForChild("Footstep")
FSevent.OnServerEvent:Connect(function(player)
local Sounds = footstepsFolder["footstep folder in audio folder"]:GetChildren()
local Sound = Sounds[math.random(1,#Sounds)]:Clone()
Sound.Parent = player.Character.UpperTorso
--Change all sounds to have PlayOnRemove property to true.
Sound:Destroy()
end)
LocalScript in StarterPlayerScripts
local RS = game:GetService("ReplicatedStorage")
local FSevent = RS:WaitForChild("Footstep")
local player = game:GetService("Players").LocalPlayer
player.CharacterAdded:Wait()
local character = player.Character
local Humanoid = character:WaitForChild("Humanoid")
local IsRunning = false
Humanoid.Running:Connect(function(speed)
if speed > 0 then
IsRunning = true
else
IsRunning = false
end
end)
task.spawn(function()
while true do
if IsRunning == true then
FSevent:FireServer()
wait(0.5)
end
task.wait(0)
end
end)
And here’s a script made by my friend to remove the default footstep noise, PUT IN StarterCharacterScripts
local hrp = script.Parent:WaitForChild("HumanoidRootPart")
local runSound = hrp:WaitForChild("Running")
if runSound then
runSound:Destroy()
end
I hope this can help someone as much as it helped me.